116 lines
1.8 KiB
Go
116 lines
1.8 KiB
Go
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("")
|
|
}
|