-
Notifications
You must be signed in to change notification settings - Fork 2
/
day11.js
92 lines (82 loc) · 2.3 KB
/
day11.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
'use strict';
const fs = require('fs');
const cl = console.log;
fs.readFile('day11.txt', 'utf-8', (err, input) => {
if (err) throw err;
let cavern = input.trim().split(/\r?\n/).map(ln => [...ln].map(Number));
cavern.width = cavern[0].length;
cavern.height = cavern.length;
dumboOctopus(cavern);
});
function dumboOctopus(cavern) {
let flashes, flashTotal = 0;
for (let step = 1; ; step++) {
flashTotal += (flashes = takeStep(cavern));
if (step === 100) {
cl(flashTotal);
}
if (flashes === 100) {
cl(step)
break
};
}
}
function takeStep(cv) {
let flashes, flashTotal = 0;
incrementAll(cv);
while ((flashes = naiveFlash(cv)) > 0) {
flashTotal += flashes;
}
return flashTotal;
}
function naiveFlash(cv) {
let flashers = allOctopodes(cv).filter(oct => get(cv, oct) > 9);
flashers
.map(oct => adjacentOct(cv, oct)).flat()
.filter(oct => get(cv, oct) > 0)
.forEach(oct => increment(cv, oct));
flashers.forEach(oct => set(cv, oct, 0));
return flashers.length;
}
function incrementAll(cv) {
allOctopodes(cv).forEach(oct => increment(cv, oct));
}
function increment(cv, oct) {
set(cv, oct, get(cv, oct) + 1);
}
function get(cv, oct) {
return cv[oct.y][oct.x];
}
function set(cv, oct, val) {
cv[oct.y][oct.x] = val;
}
function allOctopodes(cv) {
let octopodes = []
for (let x = 0; x < cv.width; x++) {
for (let y = 0; y < cv.height; y++) {
octopodes.push({ x, y });
}
}
return octopodes;
}
function adjacentOct(cv, coord) {
let { x: x, y: y } = coord;
let adjacent = [];
if (y - 1 >= 0) { adjacent.push({ x, y: y - 1 }) };
if (y - 1 >= 0 && x + 1 < cv.width) {
adjacent.push({ x: x + 1, y: y - 1 })
};
if (x + 1 < cv.width) { adjacent.push({ x: x + 1, y }) };
if (x + 1 < cv.width && y + 1 < cv.height) {
adjacent.push({ x: x + 1, y: y + 1 })
};
if (y + 1 < cv.height) { adjacent.push({ x, y: y + 1 }) };
if (y + 1 < cv.height && x - 1 >= 0) {
adjacent.push({ x: x - 1, y: y + 1 })
};
if (x - 1 >= 0) { adjacent.push({ x: x - 1, y }) };
if (x - 1 >= 0 && y - 1 >= 0) {
adjacent.push({ x: x - 1, y: y - 1 })
};
return adjacent;
}