From c0838dc944812e5107aaa80b246e52f2f092d2b7 Mon Sep 17 00:00:00 2001 From: Pascal Syma Date: Sat, 14 Dec 2024 17:14:09 +0100 Subject: [PATCH] Solve 2024-14 --- .gitignore | 1 + 2024/14/2024-14.run.xml | 7 +++ 2024/14/example-input.js | 15 ++++++ 2024/14/index.test.ts | 21 ++++++++ 2024/14/index.ts | 109 +++++++++++++++++++++++++++++++++++++++ 2024/14/run.ts | 12 +++++ 2024/14/solveSecond.html | 99 +++++++++++++++++++++++++++++++++++ 7 files changed, 264 insertions(+) create mode 100644 2024/14/2024-14.run.xml create mode 100644 2024/14/example-input.js create mode 100644 2024/14/index.test.ts create mode 100644 2024/14/index.ts create mode 100644 2024/14/run.ts create mode 100644 2024/14/solveSecond.html diff --git a/.gitignore b/.gitignore index 2930746..0448c6a 100644 --- a/.gitignore +++ b/.gitignore @@ -176,4 +176,5 @@ dist input.txt +input.js !template/input.txt \ No newline at end of file diff --git a/2024/14/2024-14.run.xml b/2024/14/2024-14.run.xml new file mode 100644 index 0000000..bedc182 --- /dev/null +++ b/2024/14/2024-14.run.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/2024/14/example-input.js b/2024/14/example-input.js new file mode 100644 index 0000000..42a9b66 --- /dev/null +++ b/2024/14/example-input.js @@ -0,0 +1,15 @@ +const xMax = 11; +const yMax = 7; + +const input = `p=0,4 v=3,-3 +p=6,3 v=-1,-3 +p=10,3 v=-1,2 +p=2,0 v=2,-1 +p=0,0 v=1,3 +p=3,0 v=-2,-2 +p=7,6 v=-1,-3 +p=3,0 v=-1,-2 +p=9,3 v=2,3 +p=7,3 v=-1,2 +p=2,4 v=2,-3 +p=9,5 v=-3,-3`; diff --git a/2024/14/index.test.ts b/2024/14/index.test.ts new file mode 100644 index 0000000..e741fb0 --- /dev/null +++ b/2024/14/index.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from 'bun:test'; +import { solveFirst } from './index.ts'; + +describe('2024-14', () => { + const testInput = `p=0,4 v=3,-3 +p=6,3 v=-1,-3 +p=10,3 v=-1,2 +p=2,0 v=2,-1 +p=0,0 v=1,3 +p=3,0 v=-2,-2 +p=7,6 v=-1,-3 +p=3,0 v=-1,-2 +p=9,3 v=2,3 +p=7,3 v=-1,2 +p=2,4 v=2,-3 +p=9,5 v=-3,-3`; + it('first', () => { + expect(solveFirst(`p=2,4 v=2,-3`, 11, 7, 0)).toBe(0); + expect(solveFirst(testInput, 11, 7)).toBe(12); + }); +}); diff --git a/2024/14/index.ts b/2024/14/index.ts new file mode 100644 index 0000000..85769c8 --- /dev/null +++ b/2024/14/index.ts @@ -0,0 +1,109 @@ +import { multArray } from '../../utils/array.ts'; +import { + calculateVariance, + type Coordinate, + CoordinateIndices, + type Coordinates, + type CoordinateSides, + isCoordinateEqual +} from '../../utils/coordinates.ts'; + +function mod(x: number, m: number) { + return ((x % m) + m) % m; +} + +export function solveFirst( + input: string, + xMax = 101, + yMax = 103, + iterations = 100 +): number { + const match = input.matchAll(/^p=(-?\d*),(-?\d*) v=(-?\d*),(-?\d*)$/gm); + + const matches = Array.from(match, (m) => ({ + p: m.slice(1, 3).map(Number) as Coordinate, + v: m.slice(3, 5).map(Number) as Coordinate + })); + + const finalPositions = matches.map( + (p) => + [ + mod(p.p[0] + p.v[0] * iterations, xMax), + mod(p.p[1] + p.v[1] * iterations, yMax) + ] as Coordinate + ); + + const centerX = Math.floor(xMax / 2); + const centerY = Math.floor(yMax / 2); + + const sumQuadrants = finalPositions.reduce( + (quads, position) => { + const [x, y] = position; + if (x < centerX) { + if (y < centerY) { + quads[0]++; + } else if (y > centerY) { + quads[3]++; + } + } else if (x > centerX) { + if (y < centerY) { + quads[1]++; + } else if (y > centerY) { + quads[2]++; + } + } + return quads; + }, + [0, 0, 0, 0] + ); + + return multArray(sumQuadrants); +} + +export function solveSecond(input: string, xMax = 101, yMax = 103): number { + const match = input.matchAll(/^p=(-?\d*),(-?\d*) v=(-?\d*),(-?\d*)$/gm); + + const matches = Array.from(match, (m) => ({ + p: m.slice(1, 3).map(Number) as Coordinate, + v: m.slice(3, 5).map(Number) as Coordinate + })); + + for (let i = 0; i < xMax * yMax; i++) { + const finalPositions = matches.map( + (p) => + [ + mod(p.p[0] + p.v[0] * i, xMax), + mod(p.p[1] + p.v[1] * i, yMax) + ] as Coordinate + ); + const oX = calculateVariance(finalPositions, CoordinateIndices.x); + + const oY = calculateVariance(finalPositions, CoordinateIndices.y); + calculateVariance([[0, 1, 2]] as CoordinateSides, CoordinateIndices.side); + + // hard coded, ups + // would be better to find the lowest oX = lX in 0-maxX and lowest oY = lY in 0-maxY + // then solve yMax * n + lY = xMax * (n+1) + lX, for n + // IDK why x+1 tho + if (oX < 600 && oY < 600) { + if (process.env.NODE_ENV === 'production') { + console.log(i, oX.toFixed(0), oY.toFixed(0)); + renderRobots(finalPositions, xMax, yMax); + } + return i; + } + } + + return 0; +} + +function renderRobots(coords: Coordinates, xMax: number, yMax: number) { + for (let y = 0; y < yMax; y++) { + const row = new Array(xMax) + .fill(' ') + .map((_, x) => + coords.some((c) => isCoordinateEqual(c, [x, y])) ? '*' : ' ' + ); + console.log(row.join('')); + } +} diff --git a/2024/14/run.ts b/2024/14/run.ts new file mode 100644 index 0000000..88783cd --- /dev/null +++ b/2024/14/run.ts @@ -0,0 +1,12 @@ +import { join } from 'path'; +import { solveFirst, solveSecond } from './index.ts'; + +const input = await Bun.file(join(__dirname, 'input.txt')).text(); + +const firstAnswer = solveFirst(input); + +console.log(firstAnswer); + +const secondAnswer = solveSecond(input); + +console.log(secondAnswer); diff --git a/2024/14/solveSecond.html b/2024/14/solveSecond.html new file mode 100644 index 0000000..1fe4f98 --- /dev/null +++ b/2024/14/solveSecond.html @@ -0,0 +1,99 @@ + + + + + AOC 2024-14 Part 2 + + + +
+ + + + + + + + +