Skip to content

Commit

Permalink
Day 14
Browse files Browse the repository at this point in the history
  • Loading branch information
hildjj committed Dec 14, 2024
1 parent 02e3099 commit 61b02c8
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 1 deletion.
4 changes: 4 additions & 0 deletions day14.peggy
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
lines = (@line "\n")*
line = "p=" @num "," @num _ "v=" @num "," @num
num = n:$("-"?[0-9]+) { return parseInt(n, 10) }
_ = [ \t]+
78 changes: 78 additions & 0 deletions day14.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Point } from './lib/rect.ts';
import { div, type MainArgs, mod, parseFile } from './lib/utils.ts';
import { Counter } from './lib/counter.ts';

type Parsed = [px: number, py: number, vx: number, vy: number][];

const STEPS = 100;
const WIDTH = 101;
const HEIGHT = 103;

function part1(inp: Parsed): number {
const pos: Point[] = [];
for (const [px, py] of inp) {
pos.push(new Point(px, py));
}

for (let j = 0; j < pos.length; j++) {
const p = pos[j];
const [_px, _py, vx, vy] = inp[j];
pos[j] = new Point(
mod(p.x + (vx * STEPS), WIDTH),
mod(p.y + (vy * STEPS), HEIGHT),
);
}

const hx = div(WIDTH, 2);
const hy = div(HEIGHT, 2);
const tots = [0, 0, 0, 0];
for (const p of pos) {
if (p.x < hx) {
if (p.y < hy) {
tots[0]++;
} else if (p.y > hy) {
tots[1]++;
}
} else if (p.x > hx) {
if (p.y < hy) {
tots[2]++;
} else if (p.y > hy) {
tots[3]++;
}
}
}
return tots.reduce((t, v) => t * v, 1);
}

function part2(inp: Parsed): number {
const pos: Point[] = [];
for (const [px, py] of inp) {
pos.push(new Point(px, py));
}

// I found the setpoints by writing images to the terminal and fiddling with
// the constants. Used Jimp and term-img.
for (let i = 0; i < Infinity; i++) {
const xc = new Counter<number>();
const yc = new Counter<number>();
for (let j = 0; j < pos.length; j++) {
const p = pos[j];
const [_px, _py, vx, vy] = inp[j];
const [nx, ny] = [mod(p.x + vx, WIDTH), mod(p.y + vy, HEIGHT)];
pos[j] = new Point(nx, ny);
xc.add(nx); // Count the number of pixels in each vertical line
yc.add(ny); // Each horizontal line
}

if (((xc.max()?.[1] ?? 0) > 30) && ((yc.max()?.[1] ?? 0) > 30)) {
// The box around the tree.
return i + 1;
}
}
return NaN;
}

export default async function main(args: MainArgs): Promise<[number, number]> {
const inp = await parseFile<Parsed>(args);
return [part1(inp), part2(inp)];
}
2 changes: 1 addition & 1 deletion inputs
6 changes: 6 additions & 0 deletions lib/rect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,12 @@ export class Rect<T = string> {
return prev;
}

fill(val: T): void {
for (let y = 0; y < this.height; y++) {
this.#vals[y].fill(val);
}
}

filter(callbackFn: RectFilterCallback<T>): Point[] {
const res: Point[] = [];
this.forEach((v, x, y) => {
Expand Down
29 changes: 29 additions & 0 deletions lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,35 @@ export function adjacentFile(
return join(p, '..', ...dir, `day${args.day}.${ext}`);
}

/**
* Create an array of the given length from a callback.
*
* @param length
* @param cb
* @returns
*/
export function toArray<T>(length: number, cb: (k: number) => T): T[] {
return Array.from({ length }, (_v, k) => cb(k));
}

export function div<T extends number | bigint>(x: T, y: T): T {
let q = (x / y) as unknown as T;
if (typeof x === 'bigint') {
const r = mod(x, y);
// Not only does Math.floor not work for BigInt, it's not needed because
// `/` does the right thing in the first place.

// except for numbers of opposite sign
if ((q < 0n) && (r > 0n)) {
// There was a remainder. JS rounded toward zero, but python
// rounds down.
q--;
}
return q;
}
return Math.floor(q as number) as T;
}

/**
* Modulo, minus the JS bug with negative numbers.
* `-5 % 4` should be `3`, not `-1`.
Expand Down
1 change: 1 addition & 0 deletions test/day14.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default [216772608, 6888];

0 comments on commit 61b02c8

Please sign in to comment.