From a87512fbf2d8a6ccadb5be25cf351c83685833ea Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Fri, 2 Dec 2022 10:35:31 -0500 Subject: [PATCH 1/8] 2022 02 --- 2022/02/part1.js | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ 2022/02/test.js | 28 +++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 2022/02/part1.js create mode 100644 2022/02/test.js diff --git a/2022/02/part1.js b/2022/02/part1.js new file mode 100644 index 0000000..b95d356 --- /dev/null +++ b/2022/02/part1.js @@ -0,0 +1,58 @@ +import * as R from "remeda"; +import { test, expect } from "vitest"; +import fs from "fs-extra"; +import path from 'path'; + +import { spy } from '../01/main.js'; + +export const sampleInput = `A Y +B X +C Z`; + +export const puzzleInput = + fs.readFileSync( path.join( path.dirname(import.meta.url), "input").replace('file:',''), "utf8"); + +const playMap = { + X: 'A', // rock + Y: 'B', // paper + Z: 'C', // scissors +} + +export const parseInput = R.createPipe( + text => text.split("\n"), + R.map( entry => entry.split(' ') ), + R.map( ([a,b]) => [a,playMap[b]] ), +) + + +const playScore = { + A: 1, + B: 2, + C: 3, +}; + +const draw = 3; +const lost = 0; +const win = 6; + +const outcome = ( opponent, me ) => { + if( opponent === me ) return draw; + if( opponent === 'A' ) { + return me === 'C' ? lost : win; + } + if( opponent === 'B' ) { + return me === 'A' ? lost : win; + } + return me === 'B' ? lost : win; +} + +export const mapScores = ([opponent,me]) => [ outcome(opponent,me), playScore[me] ]; + +export const solutionPart1 = R.createPipe( + parseInput, + R.filter( ([a]) => a ), // remove last line + R.map( mapScores ), + R.map( R.sumBy(R.identity) ), + R.sumBy(R.identity) +); + diff --git a/2022/02/test.js b/2022/02/test.js new file mode 100644 index 0000000..e59f035 --- /dev/null +++ b/2022/02/test.js @@ -0,0 +1,28 @@ +import { test, expect } from "vitest"; + +import { expectSolution } from '../01/main.js'; +import { parseInput, sampleInput, puzzleInput, mapScores, solutionPart1 } from './part1.js'; + +test( "input parsing", () => { + expect(parseInput(sampleInput)).toEqual([['A','B'],['B','A'],['C','C']]); +}); + +test( "mapScore", () => { + expect( mapScores(['A','B']) ).toEqual([6,2]); + expect( mapScores(['B','A']) ).toEqual([0,1]); + expect( mapScores(['C','C']) ).toEqual([3,3]); +}); + +test( "part 1, sample", () => { + expect( + solutionPart1(sampleInput) + ).toEqual(15) + +}); + +test("part 1", () => { + expectSolution(solutionPart1(puzzleInput)).toEqual(12458); +}); + +test.todo("part 2", () => { +}); From 8703a2c45466f0ed9c6865d6b3fb48d3c4f1d0a6 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Fri, 2 Dec 2022 10:59:27 -0500 Subject: [PATCH 2/8] part 2 --- 2022/02/part1.js | 69 ++++++++++++++++++++++++++---------------------- 2022/02/part2.js | 25 ++++++++++++++++++ 2022/02/test.js | 59 +++++++++++++++++++++++++---------------- 3 files changed, 98 insertions(+), 55 deletions(-) create mode 100644 2022/02/part2.js diff --git a/2022/02/part1.js b/2022/02/part1.js index b95d356..7172837 100644 --- a/2022/02/part1.js +++ b/2022/02/part1.js @@ -1,58 +1,63 @@ import * as R from "remeda"; import { test, expect } from "vitest"; import fs from "fs-extra"; -import path from 'path'; +import path from "path"; -import { spy } from '../01/main.js'; +import { spy } from "../01/main.js"; export const sampleInput = `A Y B X C Z`; -export const puzzleInput = - fs.readFileSync( path.join( path.dirname(import.meta.url), "input").replace('file:',''), "utf8"); +export const puzzleInput = fs.readFileSync( + path.join(path.dirname(import.meta.url), "input").replace("file:", ""), + "utf8" +); const playMap = { - X: 'A', // rock - Y: 'B', // paper - Z: 'C', // scissors -} + X: "A", // rock + Y: "B", // paper + Z: "C", // scissors +}; export const parseInput = R.createPipe( - text => text.split("\n"), - R.map( entry => entry.split(' ') ), - R.map( ([a,b]) => [a,playMap[b]] ), -) + (text) => text.split("\n"), + R.filter(R.identity), // remove last line + R.map((entry) => entry.split(" ")) +); +export const movePositions = ["A", "B", "C"]; const playScore = { - A: 1, - B: 2, - C: 3, + A: 1, + B: 2, + C: 3, }; const draw = 3; const lost = 0; const win = 6; -const outcome = ( opponent, me ) => { - if( opponent === me ) return draw; - if( opponent === 'A' ) { - return me === 'C' ? lost : win; - } - if( opponent === 'B' ) { - return me === 'A' ? lost : win; - } - return me === 'B' ? lost : win; -} +const outcome = (opponent, me) => { + if (opponent === me) return draw; + if (opponent === "A") { + return me === "C" ? lost : win; + } + if (opponent === "B") { + return me === "A" ? lost : win; + } + return me === "B" ? lost : win; +}; -export const mapScores = ([opponent,me]) => [ outcome(opponent,me), playScore[me] ]; +export const mapScores = ([opponent, me]) => [ + outcome(opponent, me), + playScore[me], +]; export const solutionPart1 = R.createPipe( - parseInput, - R.filter( ([a]) => a ), // remove last line - R.map( mapScores ), - R.map( R.sumBy(R.identity) ), - R.sumBy(R.identity) + parseInput, + R.map(([a, b]) => [a, playMap[b]]), + R.map(mapScores), + R.map(R.sumBy(R.identity)), + R.sumBy(R.identity) ); - diff --git a/2022/02/part2.js b/2022/02/part2.js new file mode 100644 index 0000000..c70ebe1 --- /dev/null +++ b/2022/02/part2.js @@ -0,0 +1,25 @@ +import * as R from "remeda"; + +import { movePositions, mapScores, playMap, parseInput } from "./part1.js"; + +function calculateMove(opponent, verdict) { + const incr = { + Y: 0, + X: 2, + Z: 1, + }; + + const index = + (movePositions.findIndex((x) => x === opponent) + incr[verdict]) % + movePositions.length; + + return movePositions[index]; +} + +export const solutionPart2 = R.createPipe( + parseInput, + R.map(([a, b]) => [a, calculateMove(a, b)]), + R.map(mapScores), + R.map(R.sumBy(R.identity)), + R.sumBy(R.identity) +); diff --git a/2022/02/test.js b/2022/02/test.js index e59f035..778928a 100644 --- a/2022/02/test.js +++ b/2022/02/test.js @@ -1,28 +1,41 @@ -import { test, expect } from "vitest"; +import { test, expect, describe } from "vitest"; -import { expectSolution } from '../01/main.js'; -import { parseInput, sampleInput, puzzleInput, mapScores, solutionPart1 } from './part1.js'; +import { expectSolution } from "../01/main.js"; +import { + parseInput, + sampleInput, + puzzleInput, + mapScores, + solutionPart1, +} from "./part1.js"; +import { solutionPart2 } from "./part2.js"; -test( "input parsing", () => { - expect(parseInput(sampleInput)).toEqual([['A','B'],['B','A'],['C','C']]); +describe("part 1", () => { + test("input parsing", () => { + expect(parseInput(sampleInput)).toEqual([ + ["A", "Y"], + ["B", "X"], + ["C", "Z"], + ]); + }); + + test("mapScore", () => { + expect(mapScores(["A", "B"])).toEqual([6, 2]); + expect(mapScores(["B", "A"])).toEqual([0, 1]); + expect(mapScores(["C", "C"])).toEqual([3, 3]); + }); + + test("part 1, sample", () => { + expect(solutionPart1(sampleInput)).toEqual(15); + }); + + test("solution", () => { + expectSolution(solutionPart1(puzzleInput)).toEqual(12458); + }); }); -test( "mapScore", () => { - expect( mapScores(['A','B']) ).toEqual([6,2]); - expect( mapScores(['B','A']) ).toEqual([0,1]); - expect( mapScores(['C','C']) ).toEqual([3,3]); -}); - -test( "part 1, sample", () => { - expect( - solutionPart1(sampleInput) - ).toEqual(15) - -}); - -test("part 1", () => { - expectSolution(solutionPart1(puzzleInput)).toEqual(12458); -}); - -test.todo("part 2", () => { +describe("part 2", () => { + test("part 2", () => { + expectSolution(solutionPart2(puzzleInput)).toEqual(12683); + }); }); From 672902f184913a9d9e01382a1553fe78a236a040 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Fri, 2 Dec 2022 11:05:04 -0500 Subject: [PATCH 3/8] add template for a new day --- 2022/template/part1.js | 1 + 2022/template/part2.js | 2 ++ 2022/template/test.js | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 2022/template/part1.js create mode 100644 2022/template/part2.js create mode 100644 2022/template/test.js diff --git a/2022/template/part1.js b/2022/template/part1.js new file mode 100644 index 0000000..b509eb0 --- /dev/null +++ b/2022/template/part1.js @@ -0,0 +1 @@ +import * as R from "remeda"; diff --git a/2022/template/part2.js b/2022/template/part2.js new file mode 100644 index 0000000..31477e8 --- /dev/null +++ b/2022/template/part2.js @@ -0,0 +1,2 @@ +import * as R from "remeda"; + diff --git a/2022/template/test.js b/2022/template/test.js new file mode 100644 index 0000000..9859a0e --- /dev/null +++ b/2022/template/test.js @@ -0,0 +1,20 @@ +import { test, expect, describe } from "vitest"; + +import { expectSolution } from "../01/main.js"; +import { + solutionPart1, + puzzleInput, +} from "./part1.js"; +import { solutionPart2 } from "./part2.js"; + +describe("part 1", () => { + test.todo("solution", () => { + expectSolution(solutionPart1(puzzleInput)).toEqual('TODO'); + }); +}); + +describe("part 2", () => { + test.todo("solution", () => { + expectSolution(solutionPart2(puzzleInput)).toEqual('TODO'); + }); +}); From 68b75967b6cf407edd93b853d9505ef3e0cb89d3 Mon Sep 17 00:00:00 2001 From: Yanick Date: Sat, 3 Dec 2022 14:52:19 -0500 Subject: [PATCH 4/8] part 1 --- 2022/03/part1.js | 23 +++++++++++++++++++++++ 2022/03/part2.js | 2 ++ 2022/03/sample | 6 ++++++ 2022/03/test.js | 29 +++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 2022/03/part1.js create mode 100644 2022/03/part2.js create mode 100644 2022/03/sample create mode 100644 2022/03/test.js diff --git a/2022/03/part1.js b/2022/03/part1.js new file mode 100644 index 0000000..a7d31f2 --- /dev/null +++ b/2022/03/part1.js @@ -0,0 +1,23 @@ +import * as R from "remeda"; +import fs from 'fs-extra'; +import path from 'path'; + +const readFile = (year,day,file) => fs.readFileSync( + path.join( year, day, file ), + "utf8" +); + +export const sample = readFile('2022','03','sample'); +export const puzzleInput = readFile('2022','03','input'); + +export const solutionPart1 = R.createPipe( + text => text.split("\n"), + R.filter( R.identity ), + R.map( line => line.split('') ), + R.map( line => [ line, line.splice( line.length / 2 ) ] ), + R.map( line => R.intersection(...line) ), + R.map( line => line[0].charCodeAt(0) ), + R.map( code => code > 96 ? code - 96 : code - 38 ), + R.sumBy( R.identity ) +); + diff --git a/2022/03/part2.js b/2022/03/part2.js new file mode 100644 index 0000000..31477e8 --- /dev/null +++ b/2022/03/part2.js @@ -0,0 +1,2 @@ +import * as R from "remeda"; + diff --git a/2022/03/sample b/2022/03/sample new file mode 100644 index 0000000..f17e726 --- /dev/null +++ b/2022/03/sample @@ -0,0 +1,6 @@ +vJrwpWtwJgWrhcsFMMfFFhFp +jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL +PmmdzqPrVvPwwTWBwg +wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn +ttgJtRGJQctTZtZT +CrZsJsPPZsGzwwsLwLmpwMDw diff --git a/2022/03/test.js b/2022/03/test.js new file mode 100644 index 0000000..95bdb5f --- /dev/null +++ b/2022/03/test.js @@ -0,0 +1,29 @@ +import { test, expect, describe } from "vitest"; + +import { + solutionPart1, + sample, + puzzleInput, +} from "./part1.js"; +import { solutionPart2 } from "./part2.js"; + +function expectSolution(result) { + console.info(result); + return expect(result); +} + +describe("part 1", () => { + test( 'sample', () => { + console.log(JSON.stringify(solutionPart1(sample))); + expectSolution(solutionPart1(sample)).toEqual(157) + }); + test("solution", () => { + expectSolution(solutionPart1(puzzleInput)).toEqual('TODO'); + }); +}); + +describe("part 2", () => { + test.todo("solution", () => { + expectSolution(solutionPart2(puzzleInput)).toEqual('TODO'); + }); +}); From 86e03e87736bc4e7ecbdbebf5cc11238fe3e7526 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Sat, 3 Dec 2022 15:26:15 -0500 Subject: [PATCH 5/8] part 2 --- 2022/03/part1.js | 31 ++++++++++++++----------------- 2022/03/part2.js | 10 ++++++++++ 2022/03/test.js | 20 ++++++++------------ 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/2022/03/part1.js b/2022/03/part1.js index a7d31f2..023ee91 100644 --- a/2022/03/part1.js +++ b/2022/03/part1.js @@ -1,23 +1,20 @@ import * as R from "remeda"; -import fs from 'fs-extra'; -import path from 'path'; +import fs from "fs-extra"; +import path from "path"; -const readFile = (year,day,file) => fs.readFileSync( - path.join( year, day, file ), - "utf8" -); +const readFile = (year, day, file) => + fs.readFileSync(path.join(year, day, file), "utf8"); -export const sample = readFile('2022','03','sample'); -export const puzzleInput = readFile('2022','03','input'); +export const sample = readFile("2022", "03", "sample"); +export const puzzleInput = readFile("2022", "03", "input"); export const solutionPart1 = R.createPipe( - text => text.split("\n"), - R.filter( R.identity ), - R.map( line => line.split('') ), - R.map( line => [ line, line.splice( line.length / 2 ) ] ), - R.map( line => R.intersection(...line) ), - R.map( line => line[0].charCodeAt(0) ), - R.map( code => code > 96 ? code - 96 : code - 38 ), - R.sumBy( R.identity ) + (text) => text.split("\n"), + R.filter(R.identity), + R.map((line) => line.split("")), + R.map((line) => [line, line.splice(line.length / 2)]), + R.map((line) => R.intersection(...line)), + R.map((line) => line[0].charCodeAt(0)), + R.map((code) => (code > 96 ? code - 96 : code - 38)), + R.sumBy(R.identity) ); - diff --git a/2022/03/part2.js b/2022/03/part2.js index 31477e8..b40e97e 100644 --- a/2022/03/part2.js +++ b/2022/03/part2.js @@ -1,2 +1,12 @@ import * as R from "remeda"; +export const solutionPart2 = R.createPipe( + (text) => text.split("\n"), + R.filter(R.identity), + R.map((line) => line.split("")), + R.chunk(3), + R.map((group) => group.reduce((a, b) => R.intersection(a, b))), + R.map((line) => line[0].charCodeAt(0)), + R.map((code) => (code > 96 ? code - 96 : code - 38)), + R.sumBy(R.identity) +); diff --git a/2022/03/test.js b/2022/03/test.js index 95bdb5f..4f1e0f8 100644 --- a/2022/03/test.js +++ b/2022/03/test.js @@ -1,10 +1,7 @@ import { test, expect, describe } from "vitest"; -import { - solutionPart1, - sample, - puzzleInput, -} from "./part1.js"; +import { solutionPart1, sample, puzzleInput } from "./part1.js"; + import { solutionPart2 } from "./part2.js"; function expectSolution(result) { @@ -13,17 +10,16 @@ function expectSolution(result) { } describe("part 1", () => { - test( 'sample', () => { - console.log(JSON.stringify(solutionPart1(sample))); - expectSolution(solutionPart1(sample)).toEqual(157) - }); + test("sample", () => { + expect(solutionPart1(sample)).toEqual(157); + }); test("solution", () => { - expectSolution(solutionPart1(puzzleInput)).toEqual('TODO'); + expectSolution(solutionPart1(puzzleInput)).toEqual(8515); }); }); describe("part 2", () => { - test.todo("solution", () => { - expectSolution(solutionPart2(puzzleInput)).toEqual('TODO'); + test("solution", () => { + expectSolution(solutionPart2(puzzleInput)).toEqual(2434); }); }); From 33a11a02dded1d97b5ee52c6706e96cde5387b95 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Sat, 3 Dec 2022 16:32:41 -0500 Subject: [PATCH 6/8] tidy up --- 2022/01/main.js | 11 +++++++++++ 2022/01/test.js | 12 +++--------- 2022/02/part1.js | 3 --- 3 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 2022/01/main.js diff --git a/2022/01/main.js b/2022/01/main.js new file mode 100644 index 0000000..453167a --- /dev/null +++ b/2022/01/main.js @@ -0,0 +1,11 @@ +import { expect } from "vitest"; + +export const spy = (x) => { + console.debug(x); + return x; +}; + +export function expectSolution(result) { + console.info(result); + return expect(result); +} diff --git a/2022/01/test.js b/2022/01/test.js index a573612..7da2d97 100644 --- a/2022/01/test.js +++ b/2022/01/test.js @@ -1,16 +1,14 @@ import * as R from "remeda"; import { test, expect } from "vitest"; import fs from "fs-extra"; +import path from 'path'; +import { expectSolution } from './main.js'; const split = (splitter) => (text) => text.split(splitter); const sum = R.sumBy(R.identity); -const spy = (x) => { - console.debug(x); - return x; -}; const input = R.pipe( - fs.readFileSync("input", "utf8"), + fs.readFileSync( path.join( path.dirname(import.meta.url), "input").replace('file:',''), "utf8"), split("\n\n"), R.map((x) => split("\n")(x) @@ -20,10 +18,6 @@ const input = R.pipe( R.map(sum) ); -function expectSolution(result) { - console.info(result); - return expect(result); -} test("part 1", () => { const maxCalories = R.pipe(input, (calories) => Math.max(...calories)); diff --git a/2022/02/part1.js b/2022/02/part1.js index 7172837..2d3eb9c 100644 --- a/2022/02/part1.js +++ b/2022/02/part1.js @@ -1,10 +1,7 @@ import * as R from "remeda"; -import { test, expect } from "vitest"; import fs from "fs-extra"; import path from "path"; -import { spy } from "../01/main.js"; - export const sampleInput = `A Y B X C Z`; From 26f9e6f5126357b60fede26452e759af9cee314a Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Sun, 4 Dec 2022 12:37:18 -0500 Subject: [PATCH 7/8] part 1 --- 2022/04/part1.js | 20 ++++++++++++++++++++ 2022/04/part2.js | 2 ++ 2022/04/sample | 6 ++++++ 2022/04/test.js | 24 ++++++++++++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 2022/04/part1.js create mode 100644 2022/04/part2.js create mode 100644 2022/04/sample create mode 100644 2022/04/test.js diff --git a/2022/04/part1.js b/2022/04/part1.js new file mode 100644 index 0000000..5c5acd2 --- /dev/null +++ b/2022/04/part1.js @@ -0,0 +1,20 @@ +import * as R from "remeda"; + +import { readFile } from '../03/part1.js'; + +export const sample = readFile("2022", "04", "sample"); +export const puzzleInput = readFile("2022", "04", "input"); + + +const rangeLength = ([a,b]) => b-a+1; + +const isContainedBy = ( [a1,a2],[b1,b2] ) => + ( (a1 >= b1) && (a2 <= b2) ); + +export const solutionPart1 = R.createPipe( + (text) => text.split("\n"), + R.filter(R.identity), + R.map( line => line.split(',').map( range => range.split('-').map( x => parseInt(x) ) ) ), + R.map( R.sortBy( x => rangeLength(x) ) ), + R.countBy( ([a,b]) => isContainedBy(a,b) ) +); diff --git a/2022/04/part2.js b/2022/04/part2.js new file mode 100644 index 0000000..31477e8 --- /dev/null +++ b/2022/04/part2.js @@ -0,0 +1,2 @@ +import * as R from "remeda"; + diff --git a/2022/04/sample b/2022/04/sample new file mode 100644 index 0000000..9f9e9cf --- /dev/null +++ b/2022/04/sample @@ -0,0 +1,6 @@ +2-4,6-8 +2-3,4-5 +5-7,7-9 +2-8,3-7 +6-6,4-6 +2-6,4-8 diff --git a/2022/04/test.js b/2022/04/test.js new file mode 100644 index 0000000..9cf5b07 --- /dev/null +++ b/2022/04/test.js @@ -0,0 +1,24 @@ +import { test, expect, describe } from "vitest"; + +import { expectSolution } from "../01/main.js"; +import { + solutionPart1, + puzzleInput, + sample, +} from "./part1.js"; +import { solutionPart2 } from "./part2.js"; + +describe("part 1", () => { + test("sample", () => { + expectSolution(solutionPart1(sample)).toEqual(2); + }); + test("solution", () => { + expectSolution(solutionPart1(puzzleInput)).toEqual('TODO'); + }); +}); + +describe("part 2", () => { + test.todo("solution", () => { + expectSolution(solutionPart2(puzzleInput)).toEqual('TODO'); + }); +}); From d9bf1d7d21cdcdf7acaa48b9a10021e9487b1b25 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Sun, 4 Dec 2022 12:42:17 -0500 Subject: [PATCH 8/8] part 2 --- 2022/03/part1.js | 2 +- 2022/04/part1.js | 16 ++++++++-------- 2022/04/part2.js | 11 +++++++++++ 2022/04/test.js | 17 ++++++++--------- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/2022/03/part1.js b/2022/03/part1.js index 023ee91..7366b96 100644 --- a/2022/03/part1.js +++ b/2022/03/part1.js @@ -2,7 +2,7 @@ import * as R from "remeda"; import fs from "fs-extra"; import path from "path"; -const readFile = (year, day, file) => +export const readFile = (year, day, file) => fs.readFileSync(path.join(year, day, file), "utf8"); export const sample = readFile("2022", "03", "sample"); diff --git a/2022/04/part1.js b/2022/04/part1.js index 5c5acd2..7a346cb 100644 --- a/2022/04/part1.js +++ b/2022/04/part1.js @@ -1,20 +1,20 @@ import * as R from "remeda"; -import { readFile } from '../03/part1.js'; +import { readFile } from "../03/part1.js"; export const sample = readFile("2022", "04", "sample"); export const puzzleInput = readFile("2022", "04", "input"); +const rangeLength = ([a, b]) => b - a + 1; -const rangeLength = ([a,b]) => b-a+1; - -const isContainedBy = ( [a1,a2],[b1,b2] ) => - ( (a1 >= b1) && (a2 <= b2) ); +const isContainedBy = ([a1, a2], [b1, b2]) => a1 >= b1 && a2 <= b2; export const solutionPart1 = R.createPipe( (text) => text.split("\n"), R.filter(R.identity), - R.map( line => line.split(',').map( range => range.split('-').map( x => parseInt(x) ) ) ), - R.map( R.sortBy( x => rangeLength(x) ) ), - R.countBy( ([a,b]) => isContainedBy(a,b) ) + R.map((line) => + line.split(",").map((range) => range.split("-").map((x) => parseInt(x))) + ), + R.map(R.sortBy((x) => rangeLength(x))), + R.countBy(([a, b]) => isContainedBy(a, b)) ); diff --git a/2022/04/part2.js b/2022/04/part2.js index 31477e8..744c09b 100644 --- a/2022/04/part2.js +++ b/2022/04/part2.js @@ -1,2 +1,13 @@ import * as R from "remeda"; +const overlapsWith = ([a1, a2], [b1, b2]) => a2 >= b1; + +export const solutionPart2 = R.createPipe( + (text) => text.split("\n"), + R.filter(R.identity), + R.map((line) => + line.split(",").map((range) => range.split("-").map((x) => parseInt(x))) + ), + R.map(R.sortBy(([x]) => x)), + R.countBy(([a, b]) => overlapsWith(a, b)) +); diff --git a/2022/04/test.js b/2022/04/test.js index 9cf5b07..a96bd6e 100644 --- a/2022/04/test.js +++ b/2022/04/test.js @@ -1,11 +1,7 @@ -import { test, expect, describe } from "vitest"; +import { test, describe } from "vitest"; import { expectSolution } from "../01/main.js"; -import { - solutionPart1, - puzzleInput, - sample, -} from "./part1.js"; +import { solutionPart1, puzzleInput, sample } from "./part1.js"; import { solutionPart2 } from "./part2.js"; describe("part 1", () => { @@ -13,12 +9,15 @@ describe("part 1", () => { expectSolution(solutionPart1(sample)).toEqual(2); }); test("solution", () => { - expectSolution(solutionPart1(puzzleInput)).toEqual('TODO'); + expectSolution(solutionPart1(puzzleInput)).toEqual(605); }); }); describe("part 2", () => { - test.todo("solution", () => { - expectSolution(solutionPart2(puzzleInput)).toEqual('TODO'); + test("sample", () => { + expectSolution(solutionPart2(sample)).toEqual(4); + }); + test("solution", () => { + expectSolution(solutionPart2(puzzleInput)).toEqual(914); }); });