Day 23 Done, I guess
This commit is contained in:
parent
08cb79c5cb
commit
847235118b
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -1,123 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
} else {
|
|
||||||
in[addr] <- <-out[i]
|
|
||||||
in[addr] <- <-out[i]
|
|
||||||
}
|
|
||||||
idle = 0
|
|
||||||
case in[i] <- -1:
|
|
||||||
idle++
|
|
||||||
}
|
|
||||||
|
|
||||||
if idle >= 50 {
|
|
||||||
if nat[1] == old[1] {
|
|
||||||
fmt.Println(nat[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
in[0] <- nat[0]
|
|
||||||
in[0] <- nat[1]
|
|
||||||
old = nat
|
|
||||||
idle = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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]
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,53 +2,122 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
pt := h.GetArgNumber(1)
|
input, _ := ioutil.ReadFile("input")
|
||||||
if pt != "2" {
|
|
||||||
part1()
|
|
||||||
} else {
|
|
||||||
part2()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func part1() {
|
// Build the memory
|
||||||
devices, queue := NewNetwork()
|
mem := map[int]int{}
|
||||||
for {
|
for i, s := range strings.Split(strings.TrimSpace(string(input)), ",") {
|
||||||
//fmt.Print(h.CLEAR_SCREEN)
|
mem[i], _ = strconv.Atoi(s)
|
||||||
for i, dev := range devices {
|
}
|
||||||
var packet h.Coordinate
|
|
||||||
if len(queue[i]) > 0 {
|
// Mesage Buffers
|
||||||
packet = queue[i][0]
|
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
|
||||||
} else {
|
} else {
|
||||||
packet = h.Coordinate{X: -1, Y: -1}
|
in[addr] <- <-out[i]
|
||||||
|
in[addr] <- <-out[i]
|
||||||
}
|
}
|
||||||
select {
|
idle = 0
|
||||||
case dest := <-dev.Channel:
|
case in[i] <- -1:
|
||||||
x := <-dev.Channel
|
idle++
|
||||||
y := <-dev.Channel
|
}
|
||||||
//fmt.Printf("%s: [%d] -> [%d]: {%d, %d}\n", time.Now().Format(time.Stamp), i, dest, x, y)
|
|
||||||
if dest == 255 {
|
if idle >= 50 {
|
||||||
fmt.Println(y)
|
if nat[1] == old[1] {
|
||||||
return
|
fmt.Println(nat[1])
|
||||||
}
|
return
|
||||||
queue[dest] = append(queue[dest], h.Coordinate{X: x, Y: y})
|
|
||||||
case dev.Channel <- packet.X:
|
|
||||||
//if packet.X != -1 && packet.Y != -1 {
|
|
||||||
// fmt.Printf("%s: [%d] <-: {%d, %d}\n", time.Now().Format(time.Stamp), i, packet.X, packet.Y)
|
|
||||||
//}
|
|
||||||
if packet.X != -1 {
|
|
||||||
dev.Channel <- packet.Y
|
|
||||||
queue[i] = queue[i][1:]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//fmt.Println(dev)
|
in[0] <- nat[0]
|
||||||
|
in[0] <- nat[1]
|
||||||
|
old = nat
|
||||||
|
idle = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func part2() {
|
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]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,163 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
|
||||||
)
|
|
||||||
|
|
||||||
var incache []int
|
|
||||||
|
|
||||||
type Computer struct {
|
|
||||||
Address int
|
|
||||||
Program []int
|
|
||||||
Position int
|
|
||||||
Offset int
|
|
||||||
Channel chan int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Computer) String() string {
|
|
||||||
status := "○"
|
|
||||||
if c.Position%2 == 0 {
|
|
||||||
status = "●"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("[%2d] %s {%d}", c.Address, status, c.Offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) parseInstruction() (int, []int) {
|
|
||||||
inst := c.read(c.Position)
|
|
||||||
opcode := inst % 100
|
|
||||||
modes := make([]int, 4)
|
|
||||||
inst /= 100
|
|
||||||
for i := 0; inst > 0; i++ {
|
|
||||||
modes[i] = inst % 10
|
|
||||||
inst /= 10
|
|
||||||
}
|
|
||||||
return opcode, modes
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) parseParameters(modes []int, num int) []int {
|
|
||||||
params := make([]int, num)
|
|
||||||
for i := 0; i < num; i++ {
|
|
||||||
if i >= len(modes) || modes[i] == 0 {
|
|
||||||
params[i] = c.read(c.read(c.Position + i + 1))
|
|
||||||
} else if modes[i] == 1 {
|
|
||||||
params[i] = c.read(c.Position + i + 1)
|
|
||||||
} else {
|
|
||||||
params[i] = c.read(c.read(c.Position+i+1) + c.Offset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) read(pos int) int {
|
|
||||||
if pos >= len(c.Program) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return c.Program[pos]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) write(pos, val, mode int) {
|
|
||||||
if mode == 2 {
|
|
||||||
pos += c.Offset
|
|
||||||
}
|
|
||||||
if pos >= len(c.Program) {
|
|
||||||
prog := make([]int, pos*2)
|
|
||||||
copy(prog, c.Program)
|
|
||||||
c.Program = prog
|
|
||||||
}
|
|
||||||
c.Program[pos] = val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) run() {
|
|
||||||
for c.read(c.Position) != 99 {
|
|
||||||
inst, modes := c.parseInstruction()
|
|
||||||
switch inst {
|
|
||||||
case 1:
|
|
||||||
params := c.parseParameters(modes, 2)
|
|
||||||
c.write(c.read(c.Position+3), params[0]+params[1], modes[2])
|
|
||||||
c.Position += 4
|
|
||||||
case 2:
|
|
||||||
params := c.parseParameters(modes, 2)
|
|
||||||
c.write(c.read(c.Position+3), params[0]*params[1], modes[2])
|
|
||||||
c.Position += 4
|
|
||||||
case 3:
|
|
||||||
c.write(c.read(c.Position+1), <-c.Channel, modes[0])
|
|
||||||
c.Position += 2
|
|
||||||
case 4:
|
|
||||||
params := c.parseParameters(modes, 1)
|
|
||||||
c.Channel <- params[0]
|
|
||||||
c.Position += 2
|
|
||||||
case 5:
|
|
||||||
params := c.parseParameters(modes, 2)
|
|
||||||
if params[0] != 0 {
|
|
||||||
c.Position = params[1]
|
|
||||||
} else {
|
|
||||||
c.Position += 3
|
|
||||||
}
|
|
||||||
case 6:
|
|
||||||
params := c.parseParameters(modes, 2)
|
|
||||||
if params[0] == 0 {
|
|
||||||
c.Position = params[1]
|
|
||||||
} else {
|
|
||||||
c.Position += 3
|
|
||||||
}
|
|
||||||
case 7:
|
|
||||||
params := c.parseParameters(modes, 2)
|
|
||||||
if params[0] < params[1] {
|
|
||||||
c.write(c.read(c.Position+3), 1, modes[2])
|
|
||||||
} else {
|
|
||||||
c.write(c.read(c.Position+3), 0, modes[2])
|
|
||||||
}
|
|
||||||
c.Position += 4
|
|
||||||
case 8:
|
|
||||||
params := c.parseParameters(modes, 2)
|
|
||||||
if params[0] == params[1] {
|
|
||||||
c.write(c.read(c.Position+3), 1, modes[2])
|
|
||||||
} else {
|
|
||||||
c.write(c.read(c.Position+3), 0, modes[2])
|
|
||||||
}
|
|
||||||
c.Position += 4
|
|
||||||
case 9:
|
|
||||||
params := c.parseParameters(modes, 1)
|
|
||||||
c.Offset += params[0]
|
|
||||||
c.Position += 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(c.Channel)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewComputer() Computer {
|
|
||||||
var ints []int
|
|
||||||
if incache == nil {
|
|
||||||
input, _ := ioutil.ReadFile("input")
|
|
||||||
ints = make([]int, 0)
|
|
||||||
for _, v := range strings.Split(string(input), ",") {
|
|
||||||
i, _ := strconv.Atoi(v)
|
|
||||||
ints = append(ints, i)
|
|
||||||
}
|
|
||||||
incache = make([]int, len(ints))
|
|
||||||
copy(incache, ints)
|
|
||||||
} else {
|
|
||||||
ints = make([]int, len(incache))
|
|
||||||
copy(ints, incache)
|
|
||||||
}
|
|
||||||
c := Computer{Program: ints, Channel: make(chan int)}
|
|
||||||
go c.run()
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewNetwork() ([]Computer, [][]h.Coordinate) {
|
|
||||||
devices := make([]Computer, 50)
|
|
||||||
queue := make([][]h.Coordinate, len(devices))
|
|
||||||
for i := 0; i < len(devices); i++ {
|
|
||||||
devices[i] = NewComputer()
|
|
||||||
devices[i].Address = i
|
|
||||||
devices[i].Channel <- i
|
|
||||||
queue[i] = make([]h.Coordinate, 0)
|
|
||||||
}
|
|
||||||
return devices, queue
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user