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