79 lines
1.4 KiB
Go
79 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
type Instruction struct {
|
|
Type string
|
|
Argument int
|
|
}
|
|
|
|
type Code []*Instruction
|
|
|
|
type Processor struct {
|
|
Accumulator int
|
|
Index int
|
|
Code Code
|
|
ExecutedInstructions []bool
|
|
}
|
|
|
|
func (p *Processor) LoadCode(code Code) {
|
|
p.Code = code
|
|
p.ExecutedInstructions = make([]bool, len(code))
|
|
p.Accumulator = 0
|
|
p.Index = 0
|
|
}
|
|
|
|
func (p *Processor) RunCurrent() (dupe bool) {
|
|
instruction := p.Code[p.Index]
|
|
switch instruction.Type {
|
|
case "acc":
|
|
p.Accumulator += instruction.Argument
|
|
p.Index++
|
|
case "jmp":
|
|
p.Index += instruction.Argument
|
|
case "nop":
|
|
p.Index++
|
|
default:
|
|
panic("invalid instruction found: " + instruction.Type)
|
|
}
|
|
dupe = p.ExecutedInstructions[p.Index]
|
|
p.ExecutedInstructions[p.Index] = true
|
|
return
|
|
}
|
|
|
|
func main() {
|
|
f, err := os.Open("input")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// "compile" code
|
|
code := Code{}
|
|
for {
|
|
instruction := new(Instruction)
|
|
_, err := fmt.Fscanf(f, "%s %d\n", &instruction.Type, &instruction.Argument)
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
code = append(code, instruction)
|
|
}
|
|
|
|
// run code until we find dupe
|
|
processor := new(Processor)
|
|
processor.LoadCode(code)
|
|
for {
|
|
dupe := processor.RunCurrent()
|
|
if dupe {
|
|
fmt.Printf("Detected dupe run, accumulator is %d\n", processor.Accumulator)
|
|
break
|
|
}
|
|
}
|
|
}
|