2020-11-03 11:02:36 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2020-11-04 15:50:08 +00:00
|
|
|
"fmt"
|
2020-11-04 15:53:07 +00:00
|
|
|
"io/ioutil"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
2020-11-03 11:02:36 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
2020-11-04 15:53:07 +00:00
|
|
|
input, _ := ioutil.ReadFile("input")
|
|
|
|
|
|
|
|
// Build the memory
|
|
|
|
mem := map[int]int{}
|
|
|
|
for i, s := range strings.Split(strings.TrimSpace(string(input)), ",") {
|
|
|
|
mem[i], _ = strconv.Atoi(s)
|
2020-11-04 14:01:21 +00:00
|
|
|
}
|
|
|
|
|
2020-11-04 15:53:07 +00:00
|
|
|
// Mesage Buffers
|
|
|
|
in, out := make([]chan int, 50), make([]chan int, 50)
|
|
|
|
for i := 0; i < 50; i++ {
|
|
|
|
in[i], out[i] = make(chan int), make(chan int)
|
|
|
|
go run(mem, in[i], out[i])
|
|
|
|
// Send address to each computer first
|
|
|
|
in[i] <- i
|
|
|
|
in[i] <- -1
|
|
|
|
}
|
|
|
|
|
|
|
|
idle := 0
|
|
|
|
var old, nat [2]int
|
|
|
|
|
|
|
|
for i := 0; ; i = (i + 1) % 50 {
|
|
|
|
select {
|
|
|
|
case addr := <-out[i]:
|
|
|
|
if addr == 255 {
|
|
|
|
new := [2]int{<-out[i], <-out[i]}
|
|
|
|
if nat == [2]int{} {
|
|
|
|
fmt.Println(new[1])
|
|
|
|
}
|
|
|
|
nat = new
|
2020-11-04 15:50:08 +00:00
|
|
|
} else {
|
2020-11-04 15:53:07 +00:00
|
|
|
in[addr] <- <-out[i]
|
|
|
|
in[addr] <- <-out[i]
|
2020-11-03 11:02:36 +00:00
|
|
|
}
|
2020-11-04 15:53:07 +00:00
|
|
|
idle = 0
|
|
|
|
case in[i] <- -1:
|
|
|
|
idle++
|
|
|
|
}
|
|
|
|
|
|
|
|
if idle >= 50 {
|
|
|
|
if nat[1] == old[1] {
|
|
|
|
fmt.Println(nat[1])
|
|
|
|
return
|
2020-11-03 11:02:36 +00:00
|
|
|
}
|
2020-11-04 15:53:07 +00:00
|
|
|
in[0] <- nat[0]
|
|
|
|
in[0] <- nat[1]
|
|
|
|
old = nat
|
|
|
|
idle = 0
|
2020-11-04 15:50:08 +00:00
|
|
|
}
|
2020-11-03 11:02:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-04 15:53:07 +00:00
|
|
|
func run(init map[int]int, in <-chan int, out chan<- int) {
|
|
|
|
ip, rb := 0, 0
|
|
|
|
mem := map[int]int{}
|
|
|
|
for i, v := range init {
|
|
|
|
mem[i] = v
|
|
|
|
}
|
|
|
|
|
|
|
|
for {
|
|
|
|
ins := fmt.Sprintf("%05d", mem[ip])
|
|
|
|
op, _ := strconv.Atoi(ins[3:])
|
|
|
|
par := func(i int) int {
|
|
|
|
switch ins[3-i] {
|
|
|
|
case '1':
|
|
|
|
return ip + i
|
|
|
|
case '2':
|
|
|
|
return rb + mem[ip+i]
|
|
|
|
default:
|
|
|
|
return mem[ip+i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch op {
|
|
|
|
case 1:
|
|
|
|
mem[par(3)] = mem[par(1)] + mem[par(2)]
|
|
|
|
case 2:
|
|
|
|
mem[par(3)] = mem[par(1)] * mem[par(2)]
|
|
|
|
case 3:
|
|
|
|
mem[par(1)] = <-in
|
|
|
|
case 4:
|
|
|
|
out <- mem[par(1)]
|
|
|
|
case 5:
|
|
|
|
if mem[par(1)] != 0 {
|
|
|
|
ip = mem[par(2)]
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
case 6:
|
|
|
|
if mem[par(1)] == 0 {
|
|
|
|
ip = mem[par(2)]
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
case 7:
|
|
|
|
if mem[par(1)] < mem[par(2)] {
|
|
|
|
mem[par(3)] = 1
|
|
|
|
} else {
|
|
|
|
mem[par(3)] = 0
|
|
|
|
}
|
|
|
|
case 8:
|
|
|
|
if mem[par(1)] == mem[par(2)] {
|
|
|
|
mem[par(3)] = 1
|
|
|
|
} else {
|
|
|
|
mem[par(3)] = 0
|
|
|
|
}
|
|
|
|
case 9:
|
|
|
|
rb += mem[par(1)]
|
|
|
|
case 99:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ip += []int{1, 4, 4, 2, 2, 3, 3, 4, 4, 2}[op]
|
|
|
|
}
|
2020-11-03 11:02:36 +00:00
|
|
|
}
|