mirror of
https://github.com/Luzifer/aoc2019.git
synced 2024-12-22 05:51:16 +00:00
Allow for callbacks as input providers
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
bf4d2ab80b
commit
5f676fd738
1 changed files with 26 additions and 2 deletions
28
intcode.go
28
intcode.go
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue