-
Notifications
You must be signed in to change notification settings - Fork 2
/
day23.go
115 lines (106 loc) · 1.75 KB
/
day23.go
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
package main
import (
"fmt"
"log"
"os"
"github.com/dhconnelly/advent-of-code-2019/intcode"
)
type packet struct {
dest int64
x, y int64
}
type machine struct {
addr int64
q []packet
in chan<- int64
out <-chan int64
snd chan<- packet
rcv chan packet
last int64
}
func (m *machine) run() {
for {
if len(m.q) > 0 {
first := m.q[0]
select {
case p := <-m.rcv:
if first.x == -1 {
m.q = m.q[1:]
}
m.q = append(m.q, p)
case dest := <-m.out:
x := <-m.out
y := <-m.out
m.snd <- packet{dest, x, y}
case m.in <- first.x:
m.q = m.q[1:]
if first.x != -1 {
m.in <- first.y
if len(m.q) == 0 {
m.q = append(m.q, packet{x: -1})
}
}
}
} else {
select {
case p := <-m.rcv:
m.q = append(m.q, p)
case dest := <-m.out:
x := <-m.out
y := <-m.out
m.snd <- packet{dest, x, y}
}
}
}
}
func newMachine(
addr int64,
prog []int64,
snd chan<- packet,
) *machine {
in := make(chan int64, 1)
in <- addr
rcv := make(chan packet)
out := intcode.RunProgram(prog, in)
m := &machine{
addr: addr,
q: []packet{{x: -1}},
rcv: rcv,
snd: snd,
in: in,
out: out,
}
go m.run()
return m
}
func machines(
n int,
prog []int64,
out chan<- packet,
) map[int64]*machine {
ms := make(map[int64]*machine)
for i := int64(0); i < int64(n); i++ {
ms[i] = newMachine(i, prog, out)
}
return ms
}
func network(n int, prog []int64) int64 {
out := make(chan packet)
ms := machines(n, prog, out)
for p := range out {
fmt.Println(p)
if p.dest == 255 {
return p.y
}
ms[p.dest].rcv <- p
}
log.Fatal("network failed")
return 0
}
func main() {
prog, err := intcode.ReadProgram(os.Args[1])
if err != nil {
log.Fatal(err)
}
fmt.Println(network(50, prog))
}