96 lines
1.7 KiB
Go
96 lines
1.7 KiB
Go
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
|
|
}
|