-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path23.js
126 lines (96 loc) Β· 2.34 KB
/
23.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
119
120
121
122
123
124
125
126
const R = require('ramda')
const intcode = require('./intcode')
const assert = require('assert')
const createNode = R.curry(function* node(rom, buffer) {
const thread = intcode.spawn(rom)
let { value, done } = thread.next()
do {
if (value.type === 'input') {
if (buffer.length === 0) {
yield true
;({ value, done } = thread.next(-1))
} else {
yield false
;({ value, done } = thread.next(buffer.splice(0, 1)[0]))
}
} else if (value.type === 'output') {
const id = value.value
;({ value, done } = thread.next())
assert.equal(value.type, 'output')
assert.equal(done, false)
const x = value.value
;({ value, done } = thread.next())
assert.equal(value.type, 'output')
assert.equal(done, false)
const y = value.value
yield [id, x, y]
;({ value, done } = thread.next())
}
} while (!done)
})
const part1 = (input) => {
const rom = intcode.parseRAM(input)
const buffers = Array(50)
.fill()
.map((_, i) => [i])
const nodes = Array(50)
.fill()
.map((_, i) => createNode(rom, buffers[i]))
for (;;) {
for (const node of nodes) {
const { value, done } = node.next()
if (done || value === true || value === false) {
continue
}
const [id, x, y] = value
if (id === 255) {
return y
}
buffers[id].push(x, y)
}
}
}
const part2 = (input) => {
const rom = intcode.parseRAM(input)
const buffers = Array(50)
.fill()
.map((_, i) => [i])
const nodes = Array(50)
.fill()
.map((_, i) => createNode(rom, buffers[i]))
let nat = null
const seen = {}
for (;;) {
let idle = 0
for (const node of nodes) {
const { value, done } = node.next()
if (done || value === false) {
continue
} else if (value === true) {
idle++
continue
} else if (Array.isArray(value)) {
const [id, x, y] = value
if (id === 255) {
nat = [x, y]
} else {
buffers[id].push(x, y)
}
} else {
throw new Error('Unreachable')
}
}
if (idle === 50 && nat !== null) {
buffers[0].push(...nat)
const naty = nat[1]
if (seen[naty]) {
return naty
}
seen[naty] = true
}
}
}
module.exports = {
part1,
part2,
}