Day 21 solution

Hopefully my logic is explained well enough in the comments for this one. We're just layering more programming languages on top of other programming languages. This is how you anger the computer gods and bring about the AI singularity.

I also made some general tweaks to the Intcode machine to make ASCII intcode machines dead simple to deal with. Is it worth the extra branches for each input and output instruction in the interpreter? Probably not...but I was never going to win any speed competitions anyway.
This commit is contained in:
2022-07-18 09:20:29 -05:00
parent effd94c09b
commit e5dd6a6ca3
5 changed files with 125 additions and 8 deletions

View File

@ -28,6 +28,8 @@ type IntcodeProgram struct {
program []int64
relativeBase int
haltRequested bool
printASCII bool
feedInput []rune
}
type IntcodeProgramState struct {
@ -140,14 +142,15 @@ func (p *IntcodeProgram) Reset() {
p.relativeBase = 0
}
func (p *IntcodeProgram) Run() {
p.RunIn(func(int) int64 { return 0 }, func(int64, IntcodeProgramState) {})
func (p *IntcodeProgram) Run() int64 {
return p.RunIn(func(int) int64 { return 0 }, func(int64, IntcodeProgramState) {})
}
func (p *IntcodeProgram) RunIn(inputFunc ProvideInputFunc, outputFunc ReceiveOutputFunc) {
func (p *IntcodeProgram) RunIn(inputFunc ProvideInputFunc, outputFunc ReceiveOutputFunc) int64 {
p.init()
inputsRequested := 0
lastOutput := int64(0)
for instructionPointer := 0; instructionPointer < len(p.program) && !p.haltRequested; {
instruction := p.GetMemory(instructionPointer)
instructionPointer++
@ -184,13 +187,28 @@ func (p *IntcodeProgram) RunIn(inputFunc ProvideInputFunc, outputFunc ReceiveOut
case opInput:
inputsRequested++
param1 := p.GetMemory(instructionPointer)
p.setMemory(int(param1), inputFunc(inputsRequested), paramModes[0])
var inputVal int64
if len(p.feedInput) > 0 {
inputVal = int64(p.feedInput[0])
p.feedInput = p.feedInput[1:]
} else {
inputVal = inputFunc(inputsRequested)
}
if p.printASCII && inputVal <= 255 {
fmt.Printf("%c", rune(inputVal))
}
p.setMemory(int(param1), inputVal, paramModes[0])
instructionPointer += 1
case opOutput:
param1 := p.GetMemory(instructionPointer)
outputFunc(p.getParamValue(int(param1), paramModes[0]), p.makeState(instructionPointer))
param1Val := p.getParamValue(int(param1), paramModes[0])
if p.printASCII && param1Val <= 255 {
fmt.Printf("%c", rune(param1Val))
}
outputFunc(param1Val, p.makeState(instructionPointer))
lastOutput = param1Val
instructionPointer += 1
@ -256,8 +274,19 @@ func (p *IntcodeProgram) RunIn(inputFunc ProvideInputFunc, outputFunc ReceiveOut
}
p.haltRequested = false
return lastOutput
}
func (p *IntcodeProgram) Stop() {
p.haltRequested = true
}
func (p *IntcodeProgram) SetDebugASCIIPrint(enable bool) {
p.printASCII = enable
}
func (p *IntcodeProgram) FeedInputString(str string) {
p.feedInput = make([]rune, len(str))
copy(p.feedInput, []rune(str))
}