func (o *opcodeComputer) tick() (done bool) {
	if o.registers[o.instructionPointer] >= len(o.instructions) {
		fmt.Println("Out of range instruction, terminating...")
		return true
	}
	instIndex := o.registers[o.instructionPointer]
	inst := o.instructions[instIndex]
	opcodeFunc := opcodeNamesToFuncs[inst.name]
	o.registers = opcodeFunc(o.registers, inst.abcValues)
	o.registers[o.instructionPointer]++
	if o.registers[o.instructionPointer] >= len(o.instructions) {
		return true
	}
	return false
}
literal opcode computer implementation, unoptimized
package main
import (
	"flag"
	"fmt"
	"strings"
	"github.com/alexchao26/advent-of-code-go/util"
)
func main() {
	var part int
	flag.IntVar(&part, "part", 1, "part 1 or 2")
	flag.Parse()
	fmt.Println("Running part", part)
	if part == 1 {
		ans := part1(util.ReadFile("./input.txt"))
		fmt.Println("Output:", ans)
	} else {
		ans := part2(util.ReadFile("./input.txt"))
		fmt.Println("Output:", ans)
	}
}
func part1(input string) int {
	opcodeComputer := parseInput(input)
	for !opcodeComputer.tick() {
		if opcodeComputer.registers[opcodeComputer.instructionPointer] == 28 {
			break
		}
	}
	return opcodeComputer.registers[5]
}
func part2(input string) int {
	opcodeComputer := parseInput(input)
	var lastReg5 int
	comparedRegister5s := map[int]bool{}
	for !opcodeComputer.tick() {
		if opcodeComputer.registers[opcodeComputer.instructionPointer] == 28 {
			reg5 := opcodeComputer.registers[5]
			if comparedRegister5s[reg5] {
				break
			}
			comparedRegister5s[reg5] = true
			lastReg5 = reg5
		}
	}
	return lastReg5
}
type opcodeComputer struct {
	instructions       []instruction
	registers          [6]int
	instructionPointer int  
}
type instruction struct {
	name      string
	abcValues [3]int
}