From 5b5bb8f50c9a44db2a85283b26a9ccbb01f8f583 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Fri, 9 Dec 2022 11:30:43 -0500 Subject: [PATCH 1/5] typo in template --- _templates/day/new/part1.ejs | 2 +- _templates/day/new/part2.ejs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_templates/day/new/part1.ejs b/_templates/day/new/part1.ejs index 14531b0..33430d6 100644 --- a/_templates/day/new/part1.ejs +++ b/_templates/day/new/part1.ejs @@ -13,4 +13,4 @@ const readInput = (...args) => export const puzzleInput = readInput(import.meta.url, "input"); export const sample = readInput(import.meta.url, "sample"); -export default = () => {}; +export default () => {}; diff --git a/_templates/day/new/part2.ejs b/_templates/day/new/part2.ejs index e59c761..ec6f9e3 100644 --- a/_templates/day/new/part2.ejs +++ b/_templates/day/new/part2.ejs @@ -4,4 +4,4 @@ to: 2022/<%= day %>/part2.js import * as R from "remeda"; -export default = () => {}; +export default () => {}; From 77b6c259c6304d9da92eb5c8ff9fe337d8cbb54a Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Fri, 9 Dec 2022 12:28:05 -0500 Subject: [PATCH 2/5] part 1 --- 2022/09/part1.js | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 2022/09/part2.js | 4 +++ 2022/09/sample | 8 ++++++ 2022/09/test.js | 40 +++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 2022/09/part1.js create mode 100644 2022/09/part2.js create mode 100644 2022/09/sample create mode 100644 2022/09/test.js diff --git a/2022/09/part1.js b/2022/09/part1.js new file mode 100644 index 0000000..3027d39 --- /dev/null +++ b/2022/09/part1.js @@ -0,0 +1,70 @@ +import * as R from "remeda"; +import Victor from "@a-robu/victor"; + +import { readFile } from "../05/part1.js"; +import { passthru } from '../08/part1.js' + +const directions = { + R: new Victor(1,0), + L: new Victor(-1,0), + U: new Victor(0,1), + D: new Victor(0,-1), +} + +const parseLine = R.createPipe( + line => line.split(" "), + ([direction,times]) => Array(parseInt(times)).fill(directions[direction]) +); + + +const readInput = (...args) => R.pipe( + readFile(...args), + text => text.split("\n"), + R.compact, + R.map( parseLine ), + R.flatten, +) + +export const puzzleInput = readInput(import.meta.url, "input"); +export const sample = readInput(import.meta.url, "sample"); + +const touching = (v1,v2) => [v1.distanceX(v2), v1.distanceY(v2)].every( + x => x*x <= 1 +); + +export function moveOnce( head, tail, d ) { + head.add(d); + + if( touching(head,tail) ) return; + + const delta = head.clone().subtract(tail).normalize(); + + if( delta.x * delta.y ) { + delta.x = delta.x > 0 ? 1 : -1; + delta.y = delta.y > 0 ? 1 : -1; + } + + tail.add(delta); +} + +const moveAround = (directives) => { + const head = new Victor(0,0); + const tail = new Victor(0,0); + + const visited = [ tail.toString() ] + + for ( const d of directives ) { + moveOnce(head,tail,d); + + visited.push( tail.toString() ); + } + + return visited; +}; + +export default R.createPipe( + moveAround, + passthru( x => console.log(x) ), + R.uniq, + R.countBy( R.identity ) +); diff --git a/2022/09/part2.js b/2022/09/part2.js new file mode 100644 index 0000000..10fc179 --- /dev/null +++ b/2022/09/part2.js @@ -0,0 +1,4 @@ +import * as R from "remeda"; + + +export default () => {}; diff --git a/2022/09/sample b/2022/09/sample new file mode 100644 index 0000000..9874df2 --- /dev/null +++ b/2022/09/sample @@ -0,0 +1,8 @@ +R 4 +U 4 +L 3 +D 1 +R 4 +D 1 +L 5 +R 2 diff --git a/2022/09/test.js b/2022/09/test.js new file mode 100644 index 0000000..4a1df81 --- /dev/null +++ b/2022/09/test.js @@ -0,0 +1,40 @@ +import { test, expect, describe } from "vitest"; +import Victor from "@a-robu/victor"; + +const V = (...args) => new Victor(...args); + +import { expectSolution } from "../01/main.js"; +import part1, { moveOnce, sample, puzzleInput } from "./part1.js"; +import part2 from "./part2.js"; + +describe("part 1", () => { + test( "moveOnce", () => { + let head = V(1,0); + let tail = V(0,0); + moveOnce(head,tail,V(1,0)); + + expect(tail).toMatchObject({x:1,y:0}); + + moveOnce(head,tail,V(0,1)); + + expect(tail).toMatchObject({x:1,y:0}); + + moveOnce(head,tail,V(0,1)); + + expect(tail).toMatchObject({x:2,y:1}); + + } ); + + test( "sample", () => { + expect(part1(sample)).toEqual(13); + } ) + test("solution", () => { + expectSolution(part1(puzzleInput)).toEqual(6030); + }); +}); + +describe("part 2", () => { + test.todo("solution", () => { + expectSolution(part2(puzzleInput)).toEqual("TODO"); + }); +}); From d59790e7d680afa4147d8256fda6d90a3c1a5d31 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Fri, 9 Dec 2022 12:33:37 -0500 Subject: [PATCH 3/5] optimize --- 2022/09/part1.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/2022/09/part1.js b/2022/09/part1.js index 3027d39..6a35258 100644 --- a/2022/09/part1.js +++ b/2022/09/part1.js @@ -35,7 +35,7 @@ const touching = (v1,v2) => [v1.distanceX(v2), v1.distanceY(v2)].every( export function moveOnce( head, tail, d ) { head.add(d); - if( touching(head,tail) ) return; + if( touching(head,tail) ) return tail.toString(); const delta = head.clone().subtract(tail).normalize(); @@ -45,26 +45,23 @@ export function moveOnce( head, tail, d ) { } tail.add(delta); + + return tail.toString(); } const moveAround = (directives) => { const head = new Victor(0,0); const tail = new Victor(0,0); - const visited = [ tail.toString() ] - - for ( const d of directives ) { - moveOnce(head,tail,d); - - visited.push( tail.toString() ); - } - - return visited; + const move = d => moveOnce(head,tail,d); + return [ + tail.toString(), + ...directives.map( move ) + ] }; export default R.createPipe( moveAround, - passthru( x => console.log(x) ), R.uniq, - R.countBy( R.identity ) + moves => moves.length ); From 45c706f93f8ff0e6e5260e418f4789ab2d1eb352 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Fri, 9 Dec 2022 13:05:42 -0500 Subject: [PATCH 4/5] part 2 --- 2022/09/bigSample | 8 +++++ 2022/09/part1.js | 82 +++++++++++++++++++++-------------------------- 2022/09/part2.js | 34 +++++++++++++++++++- 2022/09/test.js | 38 ++++++++++++---------- 4 files changed, 99 insertions(+), 63 deletions(-) create mode 100644 2022/09/bigSample diff --git a/2022/09/bigSample b/2022/09/bigSample new file mode 100644 index 0000000..60bd43b --- /dev/null +++ b/2022/09/bigSample @@ -0,0 +1,8 @@ +R 5 +U 8 +L 8 +D 3 +R 17 +D 10 +L 25 +U 20 diff --git a/2022/09/part1.js b/2022/09/part1.js index 6a35258..fcad02d 100644 --- a/2022/09/part1.js +++ b/2022/09/part1.js @@ -2,66 +2,58 @@ import * as R from "remeda"; import Victor from "@a-robu/victor"; import { readFile } from "../05/part1.js"; -import { passthru } from '../08/part1.js' +import { passthru } from "../08/part1.js"; const directions = { - R: new Victor(1,0), - L: new Victor(-1,0), - U: new Victor(0,1), - D: new Victor(0,-1), -} + R: new Victor(1, 0), + L: new Victor(-1, 0), + U: new Victor(0, 1), + D: new Victor(0, -1), +}; const parseLine = R.createPipe( - line => line.split(" "), - ([direction,times]) => Array(parseInt(times)).fill(directions[direction]) + (line) => line.split(" "), + ([direction, times]) => Array(parseInt(times)).fill(directions[direction]) ); - -const readInput = (...args) => R.pipe( - readFile(...args), - text => text.split("\n"), - R.compact, - R.map( parseLine ), - R.flatten, -) +export const readInput = (...args) => + R.pipe( + readFile(...args), + (text) => text.split("\n"), + R.compact, + R.map(parseLine), + R.flatten + ); export const puzzleInput = readInput(import.meta.url, "input"); export const sample = readInput(import.meta.url, "sample"); -const touching = (v1,v2) => [v1.distanceX(v2), v1.distanceY(v2)].every( - x => x*x <= 1 -); +export const touching = (v1, v2) => + [v1.distanceX(v2), v1.distanceY(v2)].every((x) => x * x <= 1); -export function moveOnce( head, tail, d ) { - head.add(d); +export const moveOnce = (head, tail) => (d) => { + head.add(d); - if( touching(head,tail) ) return tail.toString(); + if (touching(head, tail)) return tail.toString(); - const delta = head.clone().subtract(tail).normalize(); + const delta = head.clone().subtract(tail).normalize(); - if( delta.x * delta.y ) { - delta.x = delta.x > 0 ? 1 : -1; - delta.y = delta.y > 0 ? 1 : -1; - } + if (delta.x * delta.y) { + delta.x = delta.x > 0 ? 1 : -1; + delta.y = delta.y > 0 ? 1 : -1; + } - tail.add(delta); + tail.add(delta); - return tail.toString(); -} - -const moveAround = (directives) => { - const head = new Victor(0,0); - const tail = new Victor(0,0); - - const move = d => moveOnce(head,tail,d); - return [ - tail.toString(), - ...directives.map( move ) - ] + return tail.toString(); }; -export default R.createPipe( - moveAround, - R.uniq, - moves => moves.length -); +const moveAround = (directives) => { + const head = new Victor(0, 0); + const tail = new Victor(0, 0); + + const move = moveOnce(head, tail); + return directives.map(move); +}; + +export default R.createPipe(moveAround, R.uniq, (moves) => moves.length); diff --git a/2022/09/part2.js b/2022/09/part2.js index 10fc179..5221a09 100644 --- a/2022/09/part2.js +++ b/2022/09/part2.js @@ -1,4 +1,36 @@ import * as R from "remeda"; +import Victor from "@a-robu/victor"; +import { touching, readInput } from "./part1.js"; -export default () => {}; +export const bigSample = readInput(import.meta.url, "bigSample"); + +export const moveOnce = (knots) => (d) => { + R.first(knots).add(d); + + for (const i of R.range(1, knots.length)) { + if (touching(knots[i - 1], knots[i])) break; + + const delta = knots[i - 1].clone().subtract(knots[i]).normalize(); + + if (delta.x * delta.y) { + delta.x = delta.x > 0 ? 1 : -1; + delta.y = delta.y > 0 ? 1 : -1; + } + + knots[i].add(delta); + } + + return R.last(knots).toString(); +}; + +const moveAround = (directives) => { + const knots = Array(10) + .fill(null) + .map(() => new Victor(0, 0)); + + const move = moveOnce(knots); + return directives.map(move); +}; + +export default R.createPipe(moveAround, R.uniq, (moves) => moves.length); diff --git a/2022/09/test.js b/2022/09/test.js index 4a1df81..6692da7 100644 --- a/2022/09/test.js +++ b/2022/09/test.js @@ -5,36 +5,40 @@ const V = (...args) => new Victor(...args); import { expectSolution } from "../01/main.js"; import part1, { moveOnce, sample, puzzleInput } from "./part1.js"; -import part2 from "./part2.js"; +import part2, { bigSample } from "./part2.js"; describe("part 1", () => { - test( "moveOnce", () => { - let head = V(1,0); - let tail = V(0,0); - moveOnce(head,tail,V(1,0)); + test("moveOnce", () => { + let head = V(1, 0); + let tail = V(0, 0); + moveOnce(head, tail)(V(1, 0)); - expect(tail).toMatchObject({x:1,y:0}); + expect(tail).toMatchObject({ x: 1, y: 0 }); - moveOnce(head,tail,V(0,1)); + moveOnce(head, tail)(V(0, 1)); - expect(tail).toMatchObject({x:1,y:0}); + expect(tail).toMatchObject({ x: 1, y: 0 }); - moveOnce(head,tail,V(0,1)); + moveOnce(head, tail)(V(0, 1)); - expect(tail).toMatchObject({x:2,y:1}); + expect(tail).toMatchObject({ x: 2, y: 1 }); + }); - } ); - - test( "sample", () => { - expect(part1(sample)).toEqual(13); - } ) + test("sample", () => { + expect(part1(sample)).toEqual(13); + }); test("solution", () => { expectSolution(part1(puzzleInput)).toEqual(6030); }); }); describe("part 2", () => { - test.todo("solution", () => { - expectSolution(part2(puzzleInput)).toEqual("TODO"); + test("sample", () => { + expect(part2(sample)).toEqual(1); + expect(part2(bigSample)).toEqual(36); + }); + + test("solution", () => { + expectSolution(part2(puzzleInput)).toEqual(2545); }); }); From be1f6deda0e0b9336bc30963a6e9332743cc7bd4 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Fri, 9 Dec 2022 13:06:20 -0500 Subject: [PATCH 5/5] cm remove example template --- _templates/day/new/hello.ejs.t | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 _templates/day/new/hello.ejs.t diff --git a/_templates/day/new/hello.ejs.t b/_templates/day/new/hello.ejs.t deleted file mode 100644 index 099ef04..0000000 --- a/_templates/day/new/hello.ejs.t +++ /dev/null @@ -1,13 +0,0 @@ ---- -to: app/hello.js ---- -const hello = ``` -Hello! -This is your first hygen template. - -Learn what it can do here: - -https://github.com/jondot/hygen -``` - -console.log(hello)