1
0
Fork 0
mirror of https://github.com/Luzifer/aoc2019.git synced 2024-10-18 03:04:19 +00:00
aoc2019/intcode_test.go

197 lines
4.5 KiB
Go
Raw Permalink Normal View History

package aoc2019
import (
"reflect"
"testing"
)
func TestParseOpCode(t *testing.T) {
for code, expOpCode := range map[int64]opCode{
1002: {Type: opCodeTypeMultiplication, flags: []opCodeFlag{opCodeFlagPosition, opCodeFlagImmediate}},
1101: {Type: opCodeTypeAddition, flags: []opCodeFlag{opCodeFlagImmediate, opCodeFlagImmediate}},
} {
if op := parseOpCode(code); !op.eq(expOpCode) {
t.Errorf("OpCode execution of code %d yield unexpected result: exp=%+v got=%+v", code, expOpCode, op)
}
}
}
func TestExecuteIntcodeIO(t *testing.T) {
code, _ := parseIntcode("3,0,4,0,99")
var (
exp int64 = 25
in = make(chan int64, 1)
out = make(chan int64, 1)
)
in <- exp
if _, err := executeIntcode(code, in, out); err != nil {
t.Fatalf("Intcode execution failed: %s", err)
}
if r := <-out; r != exp {
t.Errorf("Program yield unexpected result: exp=%d got=%d", exp, r)
}
}
func TestExecuteIntcodeImmediateFlag(t *testing.T) {
// 102,4,7,0 = Multiply 4 by pos_7, store to pos_0
// 4,0 = Output pos_0
// 99 = Exit
// 3 = pos_7
code, _ := parseIntcode("102,4,7,0,4,0,99,3")
var (
exp int64 = 12
out = make(chan int64, 1)
)
if _, err := executeIntcode(code, nil, out); err != nil {
t.Fatalf("Intcode execution failed: %s", err)
}
if r := <-out; r != exp {
t.Errorf("Program yield unexpected result: exp=%d got=%d", exp, r)
}
}
func TestExecuteIntcodeEquals(t *testing.T) {
for mode, codeStr := range map[string]string{
"position": "3,9,8,9,10,9,4,9,99,-1,8",
"immediate": "3,3,1108,-1,8,3,4,3,99",
} {
for input, exp := range map[int64]int64{
1: 0,
8: 1,
20: 0,
-8: 0,
} {
var (
in = make(chan int64, 1)
out = make(chan int64, 10)
)
code, _ := parseIntcode(codeStr)
in <- input
if _, err := executeIntcode(code, in, out); err != nil {
t.Fatalf("Execute in mode %q with input %d caused an error: %s", mode, input, err)
}
if r := <-out; r != exp {
t.Errorf("Execute in mode %q with input %d yield unexpected result: exp=%d got=%d", mode, input, exp, r)
}
}
}
}
func TestExecuteIntcodeLessThan(t *testing.T) {
for mode, codeStr := range map[string]string{
"position": "3,9,7,9,10,9,4,9,99,-1,8",
"immediate": "3,3,1107,-1,8,3,4,3,99",
} {
for input, exp := range map[int64]int64{
1: 1,
8: 0,
20: 0,
-8: 1,
} {
var (
in = make(chan int64, 1)
out = make(chan int64, 10)
)
code, _ := parseIntcode(codeStr)
in <- input
if _, err := executeIntcode(code, in, out); err != nil {
t.Fatalf("Execute in mode %q with input %d caused an error: %s", mode, input, err)
}
if r := <-out; r != exp {
t.Errorf("Execute in mode %q with input %d yield unexpected result: exp=%d got=%d", mode, input, exp, r)
}
}
}
}
func TestExecuteIntcodeJump(t *testing.T) {
for mode, codeStr := range map[string]string{
"position": "3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9",
"immediate": "3,3,1105,-1,9,1101,0,0,12,4,12,99,1",
} {
for input, exp := range map[int64]int64{
5: 1,
0: 0,
} {
var (
in = make(chan int64, 1)
out = make(chan int64, 10)
)
code, _ := parseIntcode(codeStr)
in <- input
if _, err := executeIntcode(code, in, out); err != nil {
t.Fatalf("Execute in mode %q with input %d caused an error: %s", mode, input, err)
}
if r := <-out; r != exp {
t.Errorf("Execute in mode %q with input %d yield unexpected result: exp=%d got=%d", mode, input, exp, r)
}
}
}
}
func TestExecuteIntcodeRelativeBase(t *testing.T) {
code, _ := parseIntcode("109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99")
var (
codeCopy []int64
out = make(chan int64, 1)
)
go func() {
if _, err := executeIntcode(code, nil, out); err != nil {
t.Fatalf("Intcode execution failed: %s", err)
}
}()
for v := range out {
codeCopy = append(codeCopy, v)
}
if !reflect.DeepEqual(codeCopy, code) {
t.Errorf("Program yield unexpected result: exp=%d got=%d", code, codeCopy)
}
}
func TestExecuteIntcodeLargeNumber(t *testing.T) {
for codeStr, expValue := range map[string]int64{
"1102,34915192,34915192,7,4,7,99,0": 1219070632396864,
"104,1125899906842624,99": 1125899906842624,
} {
code, _ := parseIntcode(codeStr)
var out = make(chan int64, 1)
if _, err := executeIntcode(code, nil, out); err != nil {
t.Fatalf("Intcode execution failed: %s", err)
}
if r := <-out; r != expValue {
t.Errorf("Execute yield unexpected result: exp=%d got=%d", expValue, r)
}
}
}