summaryrefslogtreecommitdiff
path: root/day17
diff options
context:
space:
mode:
Diffstat (limited to 'day17')
-rw-r--r--day17/go.mod3
-rw-r--r--day17/main.go115
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("")
+}