1
0
Fork 0
mirror of https://github.com/Luzifer/aoc2019.git synced 2024-12-22 14:01:17 +00:00

Allow for callbacks as input providers

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2019-12-13 18:21:19 +01:00
parent bf4d2ab80b
commit 5f676fd738
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E

View file

@ -1,6 +1,7 @@
package aoc2019 package aoc2019
import ( import (
"log"
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
@ -8,6 +9,8 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
var intcodeDebugging = false
type opCodeFlag int64 type opCodeFlag int64
const ( const (
@ -88,8 +91,9 @@ func parseIntcode(code string) ([]int64, error) {
return out, nil return out, nil
} }
func executeIntcode(code []int64, in, out chan int64) ([]int64, error) { func executeIntcode(code []int64, in interface{}, out chan int64) ([]int64, error) {
var ( var (
inCB func() (int64, error)
pos int64 pos int64
relativeBase int64 relativeBase int64
) )
@ -98,6 +102,17 @@ func executeIntcode(code []int64, in, out chan int64) ([]int64, error) {
defer close(out) defer close(out)
} }
switch in.(type) {
case nil:
inCB = func() (int64, error) { return 0, errors.New("No input available") }
case chan int64:
inCB = func() (int64, error) { return <-(in.(chan int64)), nil }
case func() (int64, error):
inCB = in.(func() (int64, error))
default:
return nil, errors.New("Unsupported input type")
}
transformPos := func(param int64, op opCode, write bool) int64 { transformPos := func(param int64, op opCode, write bool) int64 {
var addr int64 var addr int64
@ -156,6 +171,11 @@ func executeIntcode(code []int64, in, out chan int64) ([]int64, error) {
// Position is expected to be an OpCode // Position is expected to be an OpCode
op := parseOpCode(code[pos]) op := parseOpCode(code[pos])
if intcodeDebugging {
log.Printf("OpCode execution: %#v", op)
}
switch op.Type { switch op.Type {
case opCodeTypeAddition: // p1 + p2 => p3 case opCodeTypeAddition: // p1 + p2 => p3
@ -167,7 +187,11 @@ func executeIntcode(code []int64, in, out chan int64) ([]int64, error) {
pos += 4 pos += 4
case opCodeTypeInput: // in => p1 case opCodeTypeInput: // in => p1
setParamValue(1, <-in, op) v, err := inCB()
if err != nil {
return nil, errors.Wrap(err, "Unable to read input")
}
setParamValue(1, v, op)
pos += 2 pos += 2
case opCodeTypeOutput: // p1 => out case opCodeTypeOutput: // p1 => out