From f6e0792525cb2e7497ba205b047b5aa3eb7f82ec Mon Sep 17 00:00:00 2001 From: Brian Buller Date: Wed, 4 Nov 2020 08:01:21 -0600 Subject: [PATCH] Refactoring Day 23 The normal intcode processor that I built doesn't seem to work for this. --- 2019/day23/main.go | 14 +++- 2019/day23/network.go | 121 ++++++++++++++++++++++++++++ 2019/intcode-processor/processor.go | 5 +- 3 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 2019/day23/network.go diff --git a/2019/day23/main.go b/2019/day23/main.go index ce17f70..f7409c2 100644 --- a/2019/day23/main.go +++ b/2019/day23/main.go @@ -1,11 +1,9 @@ package main import ( - "fmt" "time" intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor" - //helpers "git.bullercodeworks.com/brian/adventofcode/helpers" ) func main() { @@ -19,6 +17,15 @@ func main() { } func part1(prog []int) { + p := intcode.NewProgram(prog) + n := StartNetwork(*p) + for !n.CrashOverride { + time.Sleep(1) + } +} + +/* +func part1o(prog []int) { var network []*intcode.Program msgQueue := make([][]int, 255) for k := 0; k < 50; k++ { @@ -30,7 +37,7 @@ func part1(prog []int) { for !network[addr].NeedsInput() { time.Sleep(1) } - network[addr].Input(0) + network[addr].Input(addr) for { if !network[addr].NeedsOutput() && !network[addr].NeedsInput() { time.Sleep(1) @@ -58,6 +65,7 @@ func part1(prog []int) { } fmt.Println(msgQueue[255]) } +*/ func part2(prog []int) { } diff --git a/2019/day23/network.go b/2019/day23/network.go new file mode 100644 index 0000000..20af9c1 --- /dev/null +++ b/2019/day23/network.go @@ -0,0 +1,121 @@ +package main + +import ( + "errors" + "fmt" + "time" + + intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor" + h "git.bullercodeworks.com/brian/adventofcode/helpers" +) + +type System struct { + intcode.Program + Running bool + Address int + IncomingQueue []h.Coordinate + Network *Network +} + +func NewSystem(program intcode.Program, addr int, network *Network) *System { + s := System{ + Program: program, + Address: addr, + Network: network, + } + go func() { + fmt.Println("Booting", s.Address, "...") + for !s.Program.NeedsInput() { + time.Sleep(1) + } + s.Program.Input(s.Address) + fmt.Println(s.Address, "booted") + // System should just continue to run now + for { + if s.NeedsOutput() { + // There should be 3 outputs, an address and a coordinate + addr, x, y := s.Output(), s.Output(), s.Output() + coord := h.Coordinate{ + X: x, + Y: y, + } + s.Network.Queue(addr, coord) + } else if s.NeedsInput() { + v, err := s.Network.Retrieve(s.Address) + if err != nil { + s.Input(v.X) + for !s.NeedsInput() { + time.Sleep(1) + } + s.Input(v.Y) + } else { + s.Input(-1) + } + } + } + }() + go s.Program.Run() + return &s +} + +func (s System) String() string { + status := "." + if s.Program.NeedsInput() { + status = "<" + } else if s.Program.NeedsOutput() { + status = ">" + } + return fmt.Sprintf("[%d] %s\n", s.Address, status) +} + +type Network struct { + Systems []*System + Messages map[int][]h.Coordinate + CrashOverride bool +} + +func StartNetwork(nic intcode.Program) *Network { + n := Network{ + Messages: make(map[int][]h.Coordinate), + } + for i := 0; i < 50; i++ { + n.Systems = append(n.Systems, NewSystem(nic, i, &n)) + } + return &n +} + +func (n *Network) Queue(addr int, coord h.Coordinate) { + fmt.Println("Network Queue", addr, coord, len(n.Messages)) + if addr == 255 { + fmt.Printf("First packet to 255: {X: %d, Y: %d}\n", coord.X, coord.Y) + n.CrashOverride = true + } + if n.CrashOverride { + return + } + fmt.Printf("Queuing Packet for %d: {X: %d, Y: %d}\n", addr, coord.X, coord.Y) + n.Messages[addr] = append(n.Messages[addr], coord) +} + +func (n *Network) Retrieve(addr int) (h.Coordinate, error) { + fmt.Println("Network Retrieve", addr, len(n.Messages)) + if n.CrashOverride { + return h.Coordinate{}, errors.New("Network is down") + } + var ret h.Coordinate + if len(n.Messages[addr]) > 0 { + ret, n.Messages[addr] = n.Messages[addr][0], n.Messages[addr][1:] + fmt.Printf("%d Retriving Packet: {X: %d, Y: %d}\n", addr, ret.X, ret.Y) + return ret, nil + } else { + return h.Coordinate{}, errors.New("No message") + } +} + +func (n Network) String() string { + ret := fmt.Sprintf("Messages: %d\n", len(n.Messages)) + for v := range n.Systems { + ret = ret + n.Systems[v].String() + } + return ret +} diff --git a/2019/intcode-processor/processor.go b/2019/intcode-processor/processor.go index 21ef73b..dd3520b 100644 --- a/2019/intcode-processor/processor.go +++ b/2019/intcode-processor/processor.go @@ -3,11 +3,12 @@ package intcodeprocessor import ( "errors" "fmt" - helpers "git.bullercodeworks.com/brian/adventofcode/helpers" "io/ioutil" "math" "os" "strings" + + helpers "git.bullercodeworks.com/brian/adventofcode/helpers" ) const ( @@ -308,7 +309,7 @@ func (p *Program) set(mode, idx, v int) { func (p *Program) Input(v int) { p.input <- v - p.waitingForInput = false + //p.waitingForInput = false } func (p *Program) Output() int {