70 lines
1.3 KiB
Go
70 lines
1.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func run(p program) (acc int, err error) {
|
|
ip := 0 // Instruction Pointer
|
|
a := 0 // Accumulator "register"
|
|
for ip < len(p) { // while we're still in the program
|
|
i := &p[ip] // instruction at pointer
|
|
i.Executions = i.Executions + 1
|
|
if i.Executions == 2 {
|
|
return a, fmt.Errorf("Early exit input:%d", ip-1)
|
|
}
|
|
switch i.Op {
|
|
case "nop":
|
|
ip += 1
|
|
case "jmp":
|
|
ip += i.Arg
|
|
case "acc":
|
|
a += i.Arg
|
|
ip += 1
|
|
}
|
|
}
|
|
return a, nil
|
|
}
|
|
|
|
type instruction struct {
|
|
Executions int // Execution count
|
|
Arg int
|
|
Op string
|
|
}
|
|
|
|
type program []instruction
|
|
|
|
func main() {
|
|
d, _ := ioutil.ReadFile("input")
|
|
lines := strings.Split(string(d), "\n")
|
|
var p program
|
|
for _, l := range lines {
|
|
if l != "" {
|
|
f := strings.Fields(l)
|
|
n, _ := strconv.Atoi(f[1])
|
|
p = append(p, instruction{Arg: n, Op: f[0]})
|
|
}
|
|
}
|
|
working := make(program, len(p))
|
|
copy(working, p)
|
|
o, _ := run(working)
|
|
fmt.Println("Part 1: ", o)
|
|
for i, v := range p {
|
|
working := make(program, len(p))
|
|
copy(working, p)
|
|
if v.Op == "nop" {
|
|
working[i].Op = "jmp"
|
|
} else if v.Op == "jmp" {
|
|
working[i].Op = "nop"
|
|
}
|
|
a, err := run(working)
|
|
if err == nil {
|
|
fmt.Println("Part 2: ", a)
|
|
return
|
|
}
|
|
}
|
|
}
|