Skip to content

Commit 56fcfca

Browse files
committed
2024 day 14
1 parent c489d53 commit 56fcfca

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

2024/day14/robots.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const inputs = require("fs").readFileSync("./input.txt", "utf-8").split("\n");
2+
const mod = (n1, n2) => ((n1 % n2) + n2) % n2;
3+
4+
const WIDTH = 101,
5+
HEIGHT = 103,
6+
HALFWIDTH = 50,
7+
HALFHEIGHT = 51;
8+
9+
class Robot {
10+
/** @type {number} x */ x;
11+
/** @type {number} x */ y;
12+
/** @type {number} x */ velX;
13+
/** @type {number} x */ velY;
14+
15+
constructor(x, y, velX, velY) {
16+
this.x = x;
17+
this.y = y;
18+
this.velX = velX;
19+
this.velY = velY;
20+
}
21+
22+
move() {
23+
this.y = mod(this.y + this.velY, HEIGHT);
24+
this.x = mod(this.x + this.velX, WIDTH);
25+
26+
return this;
27+
}
28+
29+
get quad() {
30+
let [x, y, HW, HH] = [this.x, this.y, HALFWIDTH, HALFHEIGHT];
31+
32+
return x == HW || y == HH ? 4 : x < HW ? (y < HH ? 0 : 2) : y < HH ? 1 : 3;
33+
}
34+
}
35+
36+
/** @returns {Set<Robot>} */
37+
const getRobots = () => {
38+
const robots = new Set();
39+
40+
for (const input of inputs.values()) {
41+
const matches = [...input.matchAll(/-?\d+,-?\d+/g)].map((match) =>
42+
match[0].split(",").map((n) => parseInt(n))
43+
);
44+
let robot = new Robot(...matches.flat());
45+
robots.add(robot);
46+
}
47+
48+
return robots;
49+
};
50+
51+
const checkSafety = (seconds) => {
52+
const robots = getRobots();
53+
54+
for (let _ = 0; _ < 100; _++) robots.forEach((robot) => robot.move());
55+
56+
let quads = [0, 0, 0, 0];
57+
robots.forEach((robot) => {
58+
if (robot.quad < 4) quads[robot.quad]++;
59+
});
60+
61+
const safetyFactor = quads.reduce((acc, quad) => quad * acc);
62+
63+
return `Safety factor after ${seconds} seconds: ${safetyFactor}`;
64+
};
65+
66+
const findTree = (char) => {
67+
const robots = getRobots();
68+
let foundTree = false,
69+
visual = [],
70+
sec = 0;
71+
72+
const isTree = (row) => new RegExp(`${char}{31}`).test(row.join(""));
73+
74+
while (!foundTree) {
75+
visual = [];
76+
77+
robots.forEach((robot) => robot.move());
78+
sec++;
79+
80+
for (let _ = 0; _ < HEIGHT; _++) visual.push(" ".repeat(WIDTH).split(""));
81+
82+
for (const robot of robots.values())
83+
if (visual[robot.y][robot.x] == " ") visual[robot.y][robot.x] = char;
84+
85+
foundTree = visual.some(isTree);
86+
}
87+
88+
let treeStart = visual.findIndex(isTree),
89+
treeEnd = visual.findLastIndex(isTree);
90+
91+
console.log("\n[...]");
92+
console.log(
93+
visual
94+
.slice(treeStart, treeEnd + 1)
95+
.map((row) => row.join(""))
96+
.join("\n")
97+
);
98+
console.log("[...]\n");
99+
100+
return `Found tree at ${sec} seconds.`;
101+
};
102+
103+
console.log(checkSafety(100));
104+
console.log(findTree("X"));

0 commit comments

Comments
 (0)