-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path11.js
118 lines (96 loc) · 2.34 KB
/
11.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
const R = require('ramda')
const intcode = require('./intcode')
const image = require('./image')
const { parseDecimal } = require('../utils')
const vec = require('../vec')
const BLACK = 0
const WHITE = 1
const getHullColor = (hull, [x, y]) => (!hull[x] || !hull[x][y] ? BLACK : WHITE)
const setHullColor = (hull, [x, y], color) => {
if (!hull[x]) {
hull[x] = {}
}
hull[x][y] = color
}
const cw = (dir) => {
if (R.equals(dir, [0, -1])) return [1, 0]
if (R.equals(dir, [1, 0])) return [0, 1]
if (R.equals(dir, [0, 1])) return [-1, 0]
if (R.equals(dir, [-1, 0])) return [0, -1]
throw new Error(`Unknown dir ${dir}`)
}
const ccw = (dir) => {
if (R.equals(dir, [0, -1])) return [-1, 0]
if (R.equals(dir, [-1, 0])) return [0, 1]
if (R.equals(dir, [0, 1])) return [1, 0]
if (R.equals(dir, [1, 0])) return [0, -1]
throw new Error(`Unknown dir ${dir}`)
}
const paintHull = R.curry((initialColor, thread) => {
const hull = { 0: { 0: initialColor } }
let pos = [0, 0]
let dir = [0, -1]
const hullIt = (function*() {
for (;;) {
yield getHullColor(hull, pos)
}
})()
const brain = intcode.iteratorExecutor(hullIt, thread)
for (;;) {
{
const { value: color, done } = brain.next()
if (done) {
return hull
}
setHullColor(hull, pos, color)
}
{
const { value: rotation, done } = brain.next()
if (done) {
throw new Error('Expected rotation')
}
dir = rotation === 1 ? cw(dir) : ccw(dir)
pos = vec.add(pos, dir)
}
}
})
const part1 = R.pipe(
intcode.parseRAM,
intcode.spawn,
paintHull(BLACK),
R.map(R.pipe(R.keys, R.length)),
R.values,
R.sum,
)
const hullToImage = (hull) => {
const xs = R.pipe(Object.keys, R.map(parseDecimal))(hull)
const ys = R.pipe(
Object.values,
R.chain(R.pipe(Object.keys, R.map(parseDecimal))),
)(hull)
const minX = Math.min(...xs)
const maxX = Math.max(...xs)
const minY = Math.min(...ys)
const maxY = Math.max(...ys)
const w = 1 + maxX - minX
const h = 1 + maxY - minY
return Array(w)
.fill()
.map((_, x) =>
Array(h)
.fill()
.map((_, y) => getHullColor(hull, [x + minX, y + minY])),
)
}
const part2 = R.pipe(
intcode.parseRAM,
intcode.spawn,
paintHull(WHITE),
hullToImage,
R.transpose,
image.paint,
)
module.exports = {
part1,
part2,
}