package common import ( "bufio" "strconv" ) type CPU struct { registers map[string]int } func NewCPU() *CPU { return &CPU{map[string]int{"X": 1}} } func (cpu CPU) GetRegisterValue(r string) int { return cpu.registers[r] } type Instruction interface { ExecuteCycle(*CPU) bool } type NoOp struct { currentCycle int } func NewNoOp() *NoOp { return &NoOp{} } func (instruction *NoOp) ExecuteCycle(cpu *CPU) bool { instruction.currentCycle++ return instruction.currentCycle == 1 } type AddX struct { parameter int currentCycle int } func NewAddX(parameter int) *AddX { return &AddX{parameter: parameter, currentCycle: 0} } func (instruction *AddX) ExecuteCycle(cpu *CPU) bool { instruction.currentCycle++ if instruction.currentCycle == 2 { cpu.registers["X"] += instruction.parameter return true } else { return false } } type Program struct { instructions []Instruction currentInstruction int } func (program *Program) ExecuteCycles(cpu *CPU, nCycles int) bool { for i := 0; i < nCycles && program.currentInstruction < len(program.instructions); i++ { done := program.instructions[program.currentInstruction].ExecuteCycle(cpu) if done { program.currentInstruction++ } } return program.currentInstruction == len(program.instructions) } func Parse(scanner bufio.Scanner) Program { program := Program{} for scanner.Scan() { line := scanner.Text() var instruction Instruction switch line[0:4] { case "noop": instruction = NewNoOp() case "addx": value, _ := strconv.Atoi(line[5:]) instruction = NewAddX(value) } program.instructions = append(program.instructions, instruction) } return program }