Skip to content

Commit

Permalink
feat(js): add solutions for 2024 day 14
Browse files Browse the repository at this point in the history
  • Loading branch information
timkurvers committed Dec 14, 2024
1 parent 44fdcf3 commit cb18470
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
75 changes: 75 additions & 0 deletions js/src/2024/14/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* eslint-disable no-loop-func */

import { mod, multiply, solution } from '../../utils/index.js';

const SIGNED_NUMBER_MATCHER = /-?\d+/g;

const parse = (input) =>
input
.trim()
.split('\n')
.map((line) => {
const [px, py, dx, dy] = Array.from(line.matchAll(SIGNED_NUMBER_MATCHER)).map((match) =>
Number(match[0]),
);
return { px, py, dx, dy };
});

const predict = (robot, steps, width, height) => {
const px = mod(robot.px + steps * robot.dx, width);
const py = mod(robot.py + steps * robot.dy, height);
return { px, py };
};

// Whether given robot is within radial distance 1 of other robot
const isNearOther = (robot, other) => {
const diffx = Math.abs(robot.px - other.px);
const diffy = Math.abs(robot.py - other.py);
return robot !== other && diffx <= 1 && diffy <= 1;
};

// Whether this configuration of robots visually contains a hidden Christmas tree (!)
// Note: uses an arbitrary cluster threshold, as Erik sneakily decided to not let _all_ robots contribute
const isChristmasTree = (robots, threshold = 0.75) => {
const total = robots.length;
const clustered = robots.reduce((sum, robot) => sum + robots.some((other) => isNearOther(robot, other)), 0);
const percent = clustered / total;
return percent >= threshold;
};

export const partOne = solution((input, { width = 101, height = 103 }) => {
const robots = parse(input);

const middlex = (width / 2) | 0;
const middley = (height / 2) | 0;

const steps = 100;

const quadrants = [0, 0, 0, 0];

for (const robot of robots) {
const { px, py } = predict(robot, steps, width, height);
const inMiddle = px === middlex || py === middley;
if (!inMiddle) {
const index = ((((py - 1) / middley) | 0) << 1) | (((px - 1) / middlex) | 0);
quadrants[index]++;
}
}

return multiply(quadrants);
});

export const partTwo = solution.inefficient((input, { width = 101, height = 103 }) => {
const robots = parse(input);

let steps = 1;
while (true) {
const snapshot = robots.map((robot) => predict(robot, steps, width, height));
if (isChristmasTree(snapshot)) {
break;
}
++steps;
}

return steps;
});
18 changes: 18 additions & 0 deletions puzzles/2024/14/examples.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
part-one:
- 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
answer: 12
args:
width: 11
height: 7

0 comments on commit cb18470

Please sign in to comment.