diff options
Diffstat (limited to 'day17')
-rw-r--r-- | day17/go.mod | 3 | ||||
-rw-r--r-- | day17/main.go | 115 |
2 files changed, 118 insertions, 0 deletions
diff --git a/day17/go.mod b/day17/go.mod new file mode 100644 index 0000000..cc9fe5f --- /dev/null +++ b/day17/go.mod @@ -0,0 +1,3 @@ +module stevenlr.com/aoc2024/day17 + +go 1.23.3 diff --git a/day17/main.go b/day17/main.go new file mode 100644 index 0000000..7e45e94 --- /dev/null +++ b/day17/main.go @@ -0,0 +1,115 @@ +package main + +import ( + "fmt" +) + +func main() { + fmt.Println("4,6,3,5,6,3,5,2,1,0,") + execute(729, 0, 0, []byte{0, 1, 5, 4, 3, 0}) + + fmt.Println("7,1,3,4,1,2,6,7,1,") + execute(46187030, 0, 0, []byte{2, 4, 1, 5, 7, 5, 0, 3, 4, 0, 1, 6, 5, 5, 3, 0}) + + // Example + // while (a != 0) { + // a = a >> 3 + // print(a%8) + // } + + // Data + // while (a != 0) { + // b = a % 8 + // b = b ^ 5 + // c = a >> b + // a = a >> 3 + // b = b ^ c + // b = b ^ 6 + // print(b % 8) + // } + part2([]byte{2, 4, 1, 5, 7, 5, 0, 3, 4, 0, 1, 6, 5, 5, 3, 0}) +} + +func solve(ops []byte, forOp int, startingA int64) bool { + if forOp < 0 { + fmt.Println(startingA) + return true + } + + // For the last iteration, only the last 3 can be non 0. + // So we only have 8 values to test. + // For the other operands to invert, the higher bits are fixed + // so we only check the last 3 bits. + for n := range 8 { + a := (startingA << 3) | int64(n) + b := a % 8 + b = b ^ 5 + c := a >> b + b = b ^ c + b = b ^ 6 + if byte(b%8) == ops[forOp] && solve(ops, forOp-1, a) { + return true + } + } + + return false +} + +func part2(ops []byte) (a int64) { + solve(ops, len(ops)-1, 0) + return +} + +func execute(a, b, c int64, ops []byte) { + pc := 0 + + readOp := func() (op byte) { + op = ops[pc] + pc++ + return + } + + getCombo := func(op byte) int64 { + if op <= 3 { + return int64(op) + } + + switch op { + case 4: + return a + case 5: + return b + case 6: + return c + } + + panic("") + } + + for pc < len(ops)-1 { + switch readOp() { + case 0: + a = a >> getCombo(readOp()) + case 1: + b = b ^ int64(readOp()) + case 2: + b = getCombo(readOp()) % 8 + case 3: + if a != 0 { + pc = int(readOp()) + } + case 4: + b = b ^ c + pc++ + case 5: + fmt.Print(getCombo(readOp()) % 8) + fmt.Print(",") + case 6: + b = a >> getCombo(readOp()) + case 7: + c = a >> getCombo(readOp()) + } + } + + fmt.Println("") +} |