-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday14.ts
96 lines (74 loc) · 2.53 KB
/
day14.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// fucking robots again
import input from './resources/day14_input.txt' with {type: 'text'};
import * as fs from 'fs';
// change for real data
const max_width = 101;
const max_height = 103;
type Robot = {
x: number;
y: number;
vX: number;
vY: number;
};
const robots = ((input: string): Robot[] =>
input.trim().split('\n').map((line) => {
const [_, x, y, vX, vY] = line.match(/p=(\d+),(\d+) v=(-?\d+),(-?\d+)/)!.map(Number);
return { x, y, vX, vY } as Robot;
}))(input);
const tick = (robot: Robot): Robot => {
let newX = (robot.x + robot.vX) % max_width;
if (newX < 0) { newX += max_width; }
let newY = (robot.y + robot.vY) % max_height;
if (newY < 0) { newY += max_height };
return { ...robot, x: newX, y: newY };
}
const after100ticks = robots.map(robot => [...Array(100)].reduce(tick, robot));
// To determine the safest area, count the number of robots in each quadrant after 100 seconds. Robots that are exactly in the middle (horizontally or vertically) don't count as being in any quadrant
const quadrant = (x: number, y: number): number => {
const halfWidth: number = Math.floor(max_width / 2);
const halfHeight: number = Math.floor(max_height / 2);
if (x === halfWidth || y === halfHeight) {
return -1;
}
const lx = (x < halfWidth) ? 0b10 : 0b00;
const ly = (y < halfHeight) ? 0b01 : 0b00;
return lx | ly;
}
const robotsInQuadrants = (rs: Robot[]) => rs.reduce((acc, robot) => {
const q = quadrant(robot.x, robot.y);
if (q === -1) {
return acc;
}
acc[q]++;
return acc;
}, [0, 0, 0, 0]).reduce((acc: number, n: number) => acc * n, 1);
//console.log(robotsInQuadrants);
const robots2Grid = (robots: Robot[]): number[][] => {
// start with full zero grid
const grid = Array.from({ length: max_height }, () => Array.from({ length: max_width }, () => 0));
robots.forEach(({ x, y }) => {
grid[y][x] += 1;
});
return grid;
}
const visualize = (robots: Robot[]) => {
let bitmap = "P1\n" + max_width + " " + max_height + "\n";
const grid = robots2Grid(robots);
grid.forEach((row) => {
row.forEach((cell) => {
bitmap += cell > 0 ? "1" : "0";
});
bitmap += "\n";
});
return bitmap;
}
const save2File = (filename: string, content: string) =>
fs.writeFileSync(filename, content);
// generate 10000 ticks robots[] map
const all_robots = [robots];
for (let i = 0; i < 10000; i++) {
all_robots.push(all_robots[i].map(robot => tick(robot)));
}
const rank = all_robots.map((rs, i) => [i, robotsInQuadrants(rs), rs]).sort((a, b) => a[1] - b[1]).splice(0, 100);
console.log(rank[0][0]);
console.log(visualize(rank[0][2]));