-
Notifications
You must be signed in to change notification settings - Fork 1
/
day14.js
95 lines (80 loc) · 2.4 KB
/
day14.js
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
const {fetchData} = require('./util.js');
const day = 14;
let file = 'sample';
console.info(`D${day}P1 ${file}:`, part1(`./day${day}${file}.txt`));
file = 'input';
console.info(`D${day}P1 ${file}:`, part1(`./day${day}${file}.txt`));
file = 'sample';
console.info(`D${day}P2 ${file}:`, part2(`./day${day}${file}.txt`));
file = 'input';
console.info(`D${day}P2 ${file}:`, part2(`./day${day}${file}.txt`));
function part1(file) {
const grid = fetchData(file).map(r => r.split(''));
rollRocksNorth(grid);
return gridWeight(grid);
}
function part2(file) {
const grid = fetchData(file).map(r => r.split(''));
const cache = [];
let str;
let foundIndex = -1;
// Sample repeats after 9, going back to 3: (1e9 - 9) % 7 => 4, plus 9
// Input repeats after 130, going back to 109: (1e9 - 130) % 22 => 12, plus 130
for (let i = 1; i <= 142; ++i) {
rollRocksCycle(grid);
str = gridToString(grid);
foundIndex = cache.indexOf(str);
if (foundIndex >= 0) {
console.info(`${i} is a repeat of ${foundIndex + 1}`);
console.info('Weight:', gridWeight(grid));
} else {
cache.push(str);
}
}
return gridWeight(grid);
}
function rollRocksCycle(grid) {
for (const i of 'nwse') {
rollRocksNorth(grid);
rotateGrid(grid);
}
}
function rollRocksNorth(grid) {
const stoppingPoints = Array(grid[0].length).fill(-1, 0);
grid.forEach((r, ri) => {
r.forEach((c, ci) => {
if (c === '#') {
stoppingPoints[ci] = ri;
} else if (c === 'O') {
stoppingPoints[ci] += 1;
grid[ri][ci] = '.';
grid[stoppingPoints[ci]][ci] = 'O';
}
})
});
}
function rotateGrid(grid) {
const rotated = [];
for (let i = 0; i < grid[0].length; ++i) {
const newRowData = grid.map(r => r[i]).reverse();
rotated.push(newRowData);
}
grid.splice(0, grid.length, ...rotated);
}
function gridWeight(grid) {
let result = 0;
grid.forEach((r, ri) => {
r.forEach((c, ci) => {
if (c === 'O') {
result += grid.length - ri;
}
})
});
return result;
}
function gridToString(grid) {
return (grid.map(r => r.join('')).join('\n'));
}
function showGrid(grid, message='Grid') {
console.info(`${message}:\n${gridToString(grid)}`);
}