aoc2016/archive/day23/day.go

105 lines
2.2 KiB
Go

package day23
import (
"strconv"
"strings"
"tools"
)
func run(code []string, register map[string]int) map[string]int {
index := 0
for index < len(code) {
//fmt.Println("Executing line", index, ":", code[index])
instr := strings.Split(code[index], " ")
switch instr[0] {
case "cpy":
value, err := strconv.Atoi(instr[1])
if err != nil {
register[instr[2]] = register[instr[1]]
} else {
register[instr[2]] = value
}
index++
case "inc":
register[instr[1]]++
index++
case "dec":
register[instr[1]]--
index++
case "jnz":
value, err := strconv.Atoi(instr[1])
if err != nil {
value = register[instr[1]]
}
if value == 0 {
index++
} else {
jump, err := strconv.Atoi(instr[2])
if err != nil {
index += register[instr[2]]
} else {
index += jump
}
}
case "tgl":
toChange := index + register[instr[1]]
if toChange < len(code) && toChange >= 0 {
switch len(strings.Split(code[toChange], " ")) {
case 2:
if code[toChange][:3] == "inc" {
code[toChange] = "dec" + code[toChange][3:]
} else {
code[toChange] = "inc" + code[toChange][3:]
}
case 3:
if code[toChange][:3] == "jnz" {
code[toChange] = "cpy" + code[toChange][3:]
} else {
code[toChange] = "jnz" + code[toChange][3:]
}
}
}
index++
}
/*
fmt.Println("New registers", register)
fmt.Println("New code", code)
bufio.NewReader(os.Stdin).ReadBytes('\n')
*/
}
return register
}
func Part1(puzzle tools.AoCPuzzle) interface{} {
register := map[string]int{
"a": 7,
"b": 0,
"c": 0,
"d": 0,
}
register = run(puzzle.GetInputArray(), register)
return register["a"]
}
func Part2(puzzle tools.AoCPuzzle) interface{} {
register := map[string]int{
"a": 12,
"b": 0,
"c": 1,
"d": 0,
}
/*
This could be optimized by closely looking at the input and finding the "inc x" loops
and then replace them with multiplications.
Also the code seems to resemble a factorial implementation which could lead to finding
the solution without executing the code at all. Needs more analysis.
*/
register = run(puzzle.GetInputArray(), register)
return register["a"]
}