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"] }