Part 1:
I checked which operation needed to happen and enacted it. I kept a running check to see if an index was revisited. If it was, I broke out of the loop and returned the accumulation.
Part 2:
- I looked for the next jmp operation
- I changed it to a nop
- I reused the code from part1 to return the accumulation, BUT ALSO to return the index at which it terminated
- If it terminated before the end of the program, I REVERTED the last changed nop back to jmp and started again on the next jmp NOTE: I followed the running changed index with a global slice to start from in the next recursion.
- That recursion continued until I had changed only a single jmp and we reached the end of the program.
package days
import (
"fmt"
"strconv"
"strings"
inputs "../inputs"
)
// https://adventofcode.com/2020/day/8
// Eight : advent of code, day eight part1 and 2
func Eight() {
inputSlice := inputs.Day8
part1(inputSlice)
part2(inputSlice)
}
func part1(inputSlice []string) {
acc, _ := oppEvaluator(inputSlice)
fmt.Print("(Part1) - Accumulator prior to infinite loop restarting: ")
fmt.Println(acc)
}
var whichOpChanged = []int{0, 0}
func part2(inputSlice []string) {
innerSlice := inputSlice
for operation := whichOpChanged[0]; operation < len(innerSlice); operation++ {
temp := strings.Split(innerSlice[operation], " ")
typeOfOp := temp[0]
signedNumber, _ := strconv.Atoi(temp[1])
if typeOfOp == "nop" && whichOpChanged[0] == operation && whichOpChanged[1] == signedNumber {
innerSlice[whichOpChanged[0]] = "jmp " + strconv.Itoa(whichOpChanged[1])
}
if typeOfOp == "jmp" {
innerSlice[operation] = "nop " + strconv.Itoa(signedNumber)
whichOpChanged = []int{operation, signedNumber}
break
}
}
acc, in := oppEvaluator(innerSlice)
if in < len(inputSlice) {
part2(innerSlice)
} else {
fmt.Print("(Part2) - Accumulator after termination: ")
fmt.Println(acc)
}
}
func oppEvaluator(inputSlice []string) (int, int) {
accumulator := 0
operationIndex := 0
indexVisited := []int{0}
for {
temp := strings.Split(inputSlice[operationIndex], " ")
typeOfOp := temp[0]
signedNumber, _ := strconv.Atoi(temp[1])
switch typeOfOp {
case "acc":
accumulator = accumulator + signedNumber
operationIndex++
case "jmp":
operationIndex = operationIndex + signedNumber
case "nop":
operationIndex++
default:
fmt.Println("not an opp")
}
if intSliceContains(indexVisited, operationIndex) {
break
} else {
indexVisited = append(indexVisited, operationIndex)
}
if operationIndex > len(inputSlice)-1 || operationIndex < 0 {
break
}
}
return accumulator, operationIndex
}
func intSliceContains(s []int, i int) bool {
for _, a := range s {
if a == i {
return true
}
}
return false
}
Top comments (0)