-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathgrid.js
104 lines (86 loc) · 3.28 KB
/
grid.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
96
97
98
99
100
101
102
103
104
const ON = '#';
const OFF = '.';
class Grid {
constructor(initial_grid_state, stuck_corners = false) {
this.grid = JSON.parse(JSON.stringify(initial_grid_state));
this.stuck_corners = stuck_corners;
if (this.stuck_corners) {
let y = this.grid.length - 1;
let x = this.grid[0].length - 1;
this.grid[0][0] = true;
this.grid[y][0] = true;
this.grid[y][x] = true;
this.grid[0][x] = true;
}
}
coordIsCorner(x, y) {
if (y === 0 || y === this.grid.length - 1) {
return x === 0 || x === this.grid[0].length - 1;
}
return false;
}
getNeighbors(x, y) {
// prettier-ignore
let neighbors = [
[x, y - 1], // top
[x + 1, y - 1], // top right
[x + 1, y], // right
[x + 1, y + 1], // bottom right
[x, y + 1], // bottom
[x - 1, y + 1], // bottom left
[x - 1, y], // left
[x - 1, y - 1], // top left
].filter(([_x, _y]) => typeof (this.grid[_y] && this.grid[_y][_x]) !== 'undefined');
return neighbors.map(([_x, _y]) => this.grid[_y][_x]);
}
tick(steps = 1) {
for (let s = 0; s < steps; s++) {
let new_grid_state = Array(this.grid.length)
.fill()
.map(() => Array(this.grid[0].length).fill());
for (let y = 0; y < this.grid.length; y++) {
for (let x = 0; x < this.grid[0].length; x++) {
let cell = this.grid[y][x];
let neighbors = this.getNeighbors(x, y);
let neighbors_on = 0;
let neighbors_off = 0;
neighbors.forEach(n => {
if (n) neighbors_on++;
else neighbors_off++;
});
// For part two, the four corner are always in the ON state
if (this.stuck_corners && this.coordIsCorner(x, y)) {
new_grid_state[y][x] = true;
} else if (cell) {
// A light which is _on_ stays on when 2 or 3 neighbors are on,
// and turns off otherwise.
new_grid_state[y][x] = neighbors_on === 2 || neighbors_on === 3;
} else {
// A light which is _off_ turns on if exactly 3 neighbors are on,
// and stays off otherwise.
new_grid_state[y][x] = neighbors_on === 3;
}
}
}
// Update our real grid
this.grid = new_grid_state;
}
}
// Default state is ON
countLightsInState(state = true) {
let lights_in_state = 0;
for (let y = 0; y < this.grid.length; y++) {
for (let x = 0; x < this.grid[0].length; x++) {
if (this.grid[y][x] === state) {
lights_in_state++;
}
}
}
return lights_in_state;
}
printGrid() {
let grid_str = this.grid.map(row => row.map(c => (c ? ON : OFF)).join('')).join('\n');
console.log(grid_str + '\n');
}
}
module.exports = Grid;