-
Notifications
You must be signed in to change notification settings - Fork 0
/
08.js
93 lines (77 loc) · 2.07 KB
/
08.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
const R = require('ramda')
const W = 50
const H = 6
const makeScreen = (w, h) =>
Array(h)
.fill()
.map(() =>
Array(w)
.fill()
.map(() => false),
)
const countLit = (screen) =>
screen.reduce(
(lit, row) =>
lit + row.reduce((rowLit, cell) => rowLit + (cell ? 1 : 0), 0),
0,
)
const setRect = (screen, w, h) => {
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
screen[y][x] = true
}
}
}
const rotateRow = (screen, y, by) => {
screen[y] = screen[y].map(
(_, x) => screen[y][R.mathMod(x - by, screen[y].length)],
)
}
const rotateColumn = (screen, x, by) => {
const origColumn = screen.map((row) => row[x])
for (let y = 0; y < screen.length; y++) {
screen[y][x] = origColumn[R.mathMod(y - by, origColumn.length)]
}
}
const applyInstructions = (screen, instructions) => {
for (const instruction of instructions) {
const matchRect = instruction.match(/rect (\d+)x(\d+)/)
if (matchRect !== null) {
const w = parseInt(matchRect[1], 10)
const h = parseInt(matchRect[2], 10)
setRect(screen, w, h)
continue
}
const matchRow = instruction.match(/rotate row y=(\d+) by (\d+)/)
if (matchRow !== null) {
const y = parseInt(matchRow[1], 10)
const by = parseInt(matchRow[2], 10)
rotateRow(screen, y, by)
continue
}
const matchColumn = instruction.match(/rotate column x=(\d+) by (\d+)/)
if (matchColumn !== null) {
const x = parseInt(matchColumn[1], 10)
const by = parseInt(matchColumn[2], 10)
rotateColumn(screen, x, by)
continue
}
throw new Error('Unknown instruction')
}
return screen
}
const part1 = (input) =>
countLit(applyInstructions(makeScreen(W, H), input.trim().split('\n')))
const printScreen = (screen) =>
screen.map((row) => row.map((cell) => (cell ? '#' : ' ')).join('')).join('\n')
const part2 = (input) =>
'\n' +
printScreen(applyInstructions(makeScreen(W, H), input.trim().split('\n'))) +
'\n'
module.exports = {
setRect,
rotateColumn,
rotateRow,
part1,
part2,
}