Merge branch 'main' of ssh://git.bullercodeworks.com:2200/brian/adventofcode
This commit is contained in:
commit
2091f6c894
@ -1,5 +0,0 @@
|
|||||||
Register A: 0
|
|
||||||
Register B: 2024
|
|
||||||
Register C: 43690
|
|
||||||
|
|
||||||
Program: 4,0
|
|
@ -1,78 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"slices"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fmt.Println(day17(1))
|
|
||||||
fmt.Println(day17(2))
|
|
||||||
}
|
|
||||||
|
|
||||||
func day17(part int) string {
|
|
||||||
a, b, c, program := parseRegisters()
|
|
||||||
|
|
||||||
if part == 1 {
|
|
||||||
// part 1: run program and return comma-separated output
|
|
||||||
return fmt.Sprintln(runProgram(a, b, c, program))
|
|
||||||
}
|
|
||||||
|
|
||||||
// part 2: find lowest value of register A that makes the program output itself
|
|
||||||
a = 0 // the initial value of register A doesnt matter here, so we can reset it
|
|
||||||
for pos := len(program) - 1; pos >= 0; pos-- {
|
|
||||||
a <<= 3 // shift left by 3 bits
|
|
||||||
for !slices.Equal(runProgram(a, b, c, program), program[pos:]) {
|
|
||||||
a++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return strconv.Itoa(a) // return a string since part 1 needs a string
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseRegisters() (int, int, int, []int) {
|
|
||||||
return 33940147, 0, 0, []int{2, 4, 1, 5, 7, 5, 1, 6, 4, 2, 5, 5, 0, 3, 3, 0}
|
|
||||||
}
|
|
||||||
|
|
||||||
func runProgram(a, b, c int, program []int) []int {
|
|
||||||
out := make([]int, 0)
|
|
||||||
// for each isntruction pointer
|
|
||||||
for ip := 0; ip < len(program); ip += 2 {
|
|
||||||
opcode, operand := program[ip], program[ip+1]
|
|
||||||
// Process combo operand
|
|
||||||
value := operand
|
|
||||||
switch operand {
|
|
||||||
case 4:
|
|
||||||
value = a
|
|
||||||
case 5:
|
|
||||||
value = b
|
|
||||||
case 6:
|
|
||||||
value = c
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute instruction
|
|
||||||
switch opcode {
|
|
||||||
case 0: // adv - divide A by 2^value
|
|
||||||
a >>= value
|
|
||||||
case 1: // bxl - XOR B with literal
|
|
||||||
b ^= operand
|
|
||||||
case 2: // bst - set B to value mod 8
|
|
||||||
b = value % 8
|
|
||||||
case 3: // jnz - jump if A is not zero
|
|
||||||
if a != 0 {
|
|
||||||
ip = operand - 2
|
|
||||||
}
|
|
||||||
case 4: // bxc - XOR B with C
|
|
||||||
b ^= c
|
|
||||||
case 5: // out - output value mod 8
|
|
||||||
out = append(out, value%8)
|
|
||||||
case 6: // bdv - divide A by 2^value, store in B
|
|
||||||
b = a >> value
|
|
||||||
case 7: // cdv - divide A by 2^value, store in C
|
|
||||||
c = a >> value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return out
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user