Skip to content

Commit 41dc988

Browse files
committed
feat: Day 18: Settlers of The North Pole (part 2)
1 parent d5a5f8b commit 41dc988

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

day-18-settlers-of-the-north-pole/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -156,5 +156,11 @@ After 10 minutes, there are `37` wooded acres and `31` lumberyards. Multiplying
156156

157157
**What will the total resource value of the lumber collection area be after 10 minutes?**
158158

159+
## Part Two
160+
161+
This important natural resource will need to last for at least thousands of years. Are the Elves collecting this lumber sustainably?
162+
163+
**What will the total resource value of the lumber collection area be after 1000000000 minutes?**
164+
159165
## References
160166
- https://adventofcode.com/2018/day/18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
const crypto = require('crypto');
2+
3+
const countTrees = (acres) => acres.filter((a) => a === '|').length;
4+
const countLumberyards = (acres) => acres.filter((a) => a === '#').length;
5+
6+
const computeNextState = (currentState, adjacentAcres) => {
7+
const trees = countTrees(adjacentAcres);
8+
const lumberyards = countLumberyards(adjacentAcres);
9+
10+
if (currentState === '.' && trees >= 3) {
11+
return '|';
12+
}
13+
14+
if (currentState === '|' && lumberyards >= 3) {
15+
return '#';
16+
}
17+
18+
if (currentState === '#') {
19+
return lumberyards >= 1 && trees >= 1 ? '#' : '.';
20+
}
21+
22+
return currentState;
23+
};
24+
25+
const simulate = (area) => {
26+
const getAdjacentAcres = (x, y) => {
27+
const minimumX = x - 1 < 0 ? 0 : x - 1;
28+
const maximumX = x + 2 > area.length ? area.length : x + 2;
29+
const acres = [
30+
...(area[y - 1] || []).slice(minimumX, maximumX),
31+
area[y][x - 1],
32+
area[y][x + 1],
33+
...(area[y + 1] || []).slice(minimumX, maximumX),
34+
];
35+
36+
return acres.filter((acre) => acre);
37+
};
38+
39+
const output = Array
40+
.from({ length: area.length })
41+
.map(() => Array.from({ length: area.length }));
42+
43+
for (let y = 0; y < area.length; y++) {
44+
for (let x = 0; x < area.length; x++) {
45+
const adjacentAcres = getAdjacentAcres(x, y);
46+
const nextState = computeNextState(area[y][x], adjacentAcres);
47+
48+
output[y][x] = nextState;
49+
}
50+
}
51+
52+
return output;
53+
};
54+
55+
const computeSimulationHash = (area) => {
56+
const flattenedArea = area.map((row) => row.join('')).join('');
57+
const sha1 = crypto.createHash('sha1');
58+
59+
sha1.update(flattenedArea);
60+
61+
const hash = sha1.digest('hex');
62+
63+
return hash;
64+
};
65+
66+
module.exports = (input, simulations = 10) => {
67+
const previousSimulations = [];
68+
69+
const simulationArea = input
70+
.split('\n')
71+
.map((line) => line
72+
.trim()
73+
.split('')
74+
);
75+
76+
let output = simulationArea;
77+
let additionalSimulations = 0;
78+
79+
const initialHash = computeSimulationHash(output);
80+
81+
previousSimulations.push(initialHash);
82+
83+
for (let i = 0; i < simulations; i++) {
84+
output = simulate(output);
85+
86+
const hash = computeSimulationHash(output);
87+
88+
if (previousSimulations.includes(hash)) {
89+
const firstOccurrence = previousSimulations.indexOf(hash);
90+
const loopLength = previousSimulations.length - firstOccurrence;
91+
const remainingSimulations = simulations - i;
92+
93+
additionalSimulations = remainingSimulations % loopLength;
94+
95+
break;
96+
} else {
97+
previousSimulations.push(hash);
98+
}
99+
}
100+
101+
// simulate remaining mutations
102+
for (let i = 0; i < additionalSimulations - 1; i++) {
103+
output = simulate(output);
104+
}
105+
106+
const flattenedOutput = [].concat.apply([], output);
107+
108+
const trees = countTrees(flattenedOutput);
109+
const lumberyards = countLumberyards(flattenedOutput);
110+
111+
return trees * lumberyards;
112+
};

0 commit comments

Comments
 (0)