From 7c21111b121274dd95e1b2c0a1e5a72e081e6bdf Mon Sep 17 00:00:00 2001 From: Brian Buller Date: Fri, 23 Dec 2016 11:11:11 -0600 Subject: [PATCH] Day 23 Progress --- 2016/day22/main.go | 13 ++- 2016/day23/input | 26 +++++ 2016/day23/main.go | 223 +++++++++++++++++++++++++++++++++++++++++++ 2016/day23/testinput | 7 ++ 4 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 2016/day23/input create mode 100644 2016/day23/main.go create mode 100644 2016/day23/testinput diff --git a/2016/day22/main.go b/2016/day22/main.go index 787c239..ef332c9 100644 --- a/2016/day22/main.go +++ b/2016/day22/main.go @@ -53,13 +53,22 @@ func main() { } else { fmt.Println(CenterText("Exit", tWidth)) } + fmt.Println() + fmt.Println(CenterText("To run the AdventOfCode Puzzle, pass the input as an argument to the program:", tWidth)) + fmt.Println(CenterText("./day22 ", tWidth)) + fmt.Println(CenterText("For the part 1 solution:", tWidth)) + fmt.Println(CenterText("./day22 -1", tWidth)) ev := termbox.PollEvent() if ev.Type == termbox.EventKey { switch { case ev.Key == termbox.KeyArrowUp || ev.Ch == 'k': - menuPos-- + if menuPos > 0 { + menuPos-- + } case ev.Key == termbox.KeyArrowDown || ev.Ch == 'j': - menuPos++ + if menuPos < 3 { + menuPos++ + } case ev.Key == termbox.KeyEnter: done = true } diff --git a/2016/day23/input b/2016/day23/input new file mode 100644 index 0000000..45e8bad --- /dev/null +++ b/2016/day23/input @@ -0,0 +1,26 @@ +cpy a b +dec b +cpy a d +cpy 0 a +cpy b c +inc a +dec c +jnz c -2 +dec d +jnz d -5 +dec b +cpy b c +cpy c d +dec d +inc c +jnz d -2 +tgl c +cpy -16 c +jnz 1 c +cpy 72 c +jnz 77 d +inc a +inc d +jnz d -2 +inc c +jnz c -5 diff --git a/2016/day23/main.go b/2016/day23/main.go new file mode 100644 index 0000000..775b471 --- /dev/null +++ b/2016/day23/main.go @@ -0,0 +1,223 @@ +package main + +import ( + "fmt" + "os" + "strings" + "time" + + termbox "github.com/nsf/termbox-go" + + "../../" +) + +var regs = map[string]int{ + "a": 12, + "b": 0, + "c": 0, + "d": 0, +} + +var instructions []string +var curr int +var pause bool + +func main() { + var debug bool + var inpFn string + var done bool + if inpFn = aoc.GetArgNumber(1); inpFn == "" { + done = true + } + if inpFn != "" { + instructions = aoc.FileToStringSlice(inpFn) + } + + if aoc.ArgIsSet("-d") { + debug = true + } + if aoc.ArgIsSet("-p") { + pause = true + } + err := termbox.Init() + //tWidth, tHeight := termbox.Size() + if err != nil { + fmt.Println("Error initializing termbox") + os.Exit(1) + } + + defer termbox.Close() + eventChan := make(chan termbox.Event) + go readUserInput(eventChan) + go sendNoneEvent(eventChan) + curr = 0 + // Find a set of instructions that look like: + // inc a + // dec c + // jnz c -2 + // and convert them to: + // mlt a c a + // cpy 0 c + for curr < len(instructions) || done { + if debug { + // print state and wait for user to step + PrintState() + PrintInstructionState() + fmt.Println("(q): quit (space): pause/unpause") + ev := <-eventChan + if ev.Type == termbox.EventKey { + if ev.Key == termbox.KeySpace { + pause = !pause + } + if ev.Ch == 'q' { + break + } + } + } + ins := strings.Fields(instructions[curr]) + curr++ + /* + // TODO: + > cpy b c + inc a + dec c + jnz c -2 + dec d + jnz d -5 + == mult b d a + and curr += 6 + */ + switch ins[0] { + case "jnz": + // If we have a jnz c -2 it could be moving all of c into another register + v, ok := regs[ins[1]] + if !ok { + v = aoc.Atoi(ins[1]) + } + var p int + if p, ok = regs[ins[2]]; !ok { + p = aoc.Atoi(ins[2]) + } + if v != 0 { + // Subtract 1 from the jump because we incremented already + curr += p - 1 + } + case "mlt": + // a three arg instruction: mlt a b c + // take a * b, store in c + var ok bool + src1 := ins[1] + src2 := ins[2] + dst := ins[3] + if _, ok := regs[dst]; !ok { + // invalid destination + continue + } + var src1I, src2I int + if src1I, ok = regs[src1]; !ok { + src1I = aoc.Atoi(src1) + } + if src2I, ok = regs[src2]; !ok { + src2I = aoc.Atoi(src2) + } + regs[dst] = src1I * src2I + case "cpy": + src := ins[1] + dst := ins[2] + // check if dst is a register + if _, ok := regs[dst]; !ok { + // Nope, move along + continue + } + // check if the src is a register + if v, ok := regs[src]; ok { + regs[dst] = v + } else { + // It's not, must be an int + regs[dst] = aoc.Atoi(src) + } + case "inc": + if _, ok := regs[ins[1]]; !ok { + continue + } + regs[ins[1]] = regs[ins[1]] + 1 + case "dec": + if _, ok := regs[ins[1]]; !ok { + continue + } + regs[ins[1]] = regs[ins[1]] - 1 + case "tgl": // tgl alters an instruction + src := ins[1] + var srcI int + if v, ok := regs[src]; ok { + srcI = v + } else { + srcI = aoc.Atoi(src) + } + srcI = curr + srcI + if srcI < 0 || srcI > len(instructions)-1 { + // Invalid instruction + continue + } + altPts := strings.Fields(instructions[srcI-1]) + if len(altPts) == 2 { // one argument + if altPts[0] == "inc" { + altPts[0] = "dec" + } else { + altPts[0] = "inc" + } + } else { // two arguments + if altPts[0] == "jnz" { + altPts[0] = "cpy" + } else { + altPts[0] = "jnz" + } + } + instructions[srcI-1] = strings.Join(altPts, " ") + } + if debug { + PrintState() + } + } + PrintState() +} + +// Fancy State Printing +func PrintState() { + fmt.Println(aoc.ClearScreen) + PrintRegs() +} + +func PrintRegs() { + datLine := fmt.Sprint("\u2502 a:", regs["a"], " b:", regs["b"], " c:", regs["c"], " d:", regs["d"], " \u2502") + fmt.Println("\u250C" + strings.Repeat("\u2500", len(datLine)-6) + "\u2510") + fmt.Println(datLine) + fmt.Println("\u2514" + strings.Repeat("\u2500", len(datLine)-6) + "\u2518") +} + +func PrintInstructionState() { + for pi := range instructions { + if pi == curr { + fmt.Print("> ") + } else { + fmt.Print(" ") + } + fmt.Println(instructions[pi]) + } + fmt.Println(instructions[curr]) +} + +func readUserInput(e chan termbox.Event) { + for { + e <- termbox.PollEvent() + } +} + +func sendNoneEvent(e chan termbox.Event) { + for { + time.Sleep(time.Second / 32) + if !pause { + e <- termbox.Event{Type: termbox.EventNone} + } + } +} diff --git a/2016/day23/testinput b/2016/day23/testinput new file mode 100644 index 0000000..bcabc2c --- /dev/null +++ b/2016/day23/testinput @@ -0,0 +1,7 @@ +cpy 2 a +tgl a +tgl a +tgl a +cpy 1 a +dec a +dec a