2019 day 9 Complete!

This commit is contained in:
Brian Buller 2019-12-09 07:32:24 -06:00
parent 5b5e519ddf
commit 7cc0053b33
7 changed files with 156 additions and 30 deletions

17
2019/day08/main.go Normal file
View File

@ -0,0 +1,17 @@
package main
import (
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
inp := helpers.StdinToStringSlice()
part1(inp)
part2(inp)
}
func part1(inp []string) {
}
func part2(inp []string) {
}

1
2019/day09/input Normal file
View File

@ -0,0 +1 @@
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,3,1,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,521,1,1028,1101,0,36,1000,1102,30,1,1005,1101,21,0,1013,1101,26,0,1006,1102,31,1,1017,1101,24,0,1007,1101,0,1,1021,1102,27,1,1019,1101,23,0,1010,1101,0,38,1012,1102,35,1,1001,1101,25,0,1003,1102,20,1,1004,1101,0,37,1009,1101,424,0,1023,1102,39,1,1008,1102,406,1,1027,1102,1,413,1026,1101,0,29,1002,1102,1,0,1020,1102,34,1,1014,1102,1,28,1018,1102,1,33,1011,1102,300,1,1025,1102,1,22,1015,1102,305,1,1024,1101,32,0,1016,1102,427,1,1022,1101,512,0,1029,109,14,1205,6,197,1001,64,1,64,1106,0,199,4,187,1002,64,2,64,109,-18,1207,8,19,63,1005,63,215,1105,1,221,4,205,1001,64,1,64,1002,64,2,64,109,10,1208,-1,28,63,1005,63,237,1106,0,243,4,227,1001,64,1,64,1002,64,2,64,109,-2,2102,1,0,63,1008,63,22,63,1005,63,263,1105,1,269,4,249,1001,64,1,64,1002,64,2,64,109,11,21107,40,39,0,1005,1015,289,1001,64,1,64,1106,0,291,4,275,1002,64,2,64,109,9,2105,1,0,4,297,1105,1,309,1001,64,1,64,1002,64,2,64,109,-13,2101,0,-5,63,1008,63,25,63,1005,63,329,1105,1,335,4,315,1001,64,1,64,1002,64,2,64,109,1,1206,8,353,4,341,1001,64,1,64,1105,1,353,1002,64,2,64,109,3,2108,37,-6,63,1005,63,375,4,359,1001,64,1,64,1106,0,375,1002,64,2,64,109,-16,1207,2,36,63,1005,63,397,4,381,1001,64,1,64,1105,1,397,1002,64,2,64,109,28,2106,0,0,1001,64,1,64,1106,0,415,4,403,1002,64,2,64,109,-3,2105,1,-1,1106,0,433,4,421,1001,64,1,64,1002,64,2,64,109,-12,2108,25,-6,63,1005,63,449,1105,1,455,4,439,1001,64,1,64,1002,64,2,64,109,-19,1202,8,1,63,1008,63,38,63,1005,63,479,1001,64,1,64,1105,1,481,4,461,1002,64,2,64,109,14,2107,25,0,63,1005,63,497,1105,1,503,4,487,1001,64,1,64,1002,64,2,64,109,24,2106,0,-3,4,509,1001,64,1,64,1105,1,521,1002,64,2,64,109,-20,1208,-2,37,63,1005,63,543,4,527,1001,64,1,64,1106,0,543,1002,64,2,64,109,7,21102,41,1,0,1008,1018,43,63,1005,63,563,1105,1,569,4,549,1001,64,1,64,1002,64,2,64,109,-7,1205,10,587,4,575,1001,64,1,64,1106,0,587,1002,64,2,64,109,-11,1202,5,1,63,1008,63,30,63,1005,63,609,4,593,1106,0,613,1001,64,1,64,1002,64,2,64,109,4,1201,5,0,63,1008,63,34,63,1005,63,637,1001,64,1,64,1105,1,639,4,619,1002,64,2,64,109,12,1206,5,651,1105,1,657,4,645,1001,64,1,64,1002,64,2,64,109,9,21101,42,0,-7,1008,1018,39,63,1005,63,677,1105,1,683,4,663,1001,64,1,64,1002,64,2,64,109,-2,21101,43,0,-8,1008,1015,43,63,1005,63,705,4,689,1106,0,709,1001,64,1,64,1002,64,2,64,109,-25,2107,38,10,63,1005,63,727,4,715,1106,0,731,1001,64,1,64,1002,64,2,64,109,7,2102,1,2,63,1008,63,24,63,1005,63,757,4,737,1001,64,1,64,1105,1,757,1002,64,2,64,109,-13,1201,10,0,63,1008,63,29,63,1005,63,779,4,763,1105,1,783,1001,64,1,64,1002,64,2,64,109,30,21108,44,41,-3,1005,1019,803,1001,64,1,64,1106,0,805,4,789,1002,64,2,64,109,-2,21102,45,1,-7,1008,1013,45,63,1005,63,827,4,811,1105,1,831,1001,64,1,64,1002,64,2,64,109,-16,21107,46,47,7,1005,1011,849,4,837,1106,0,853,1001,64,1,64,1002,64,2,64,109,9,21108,47,47,0,1005,1013,875,4,859,1001,64,1,64,1106,0,875,1002,64,2,64,109,-10,2101,0,2,63,1008,63,30,63,1005,63,901,4,881,1001,64,1,64,1105,1,901,4,64,99,21102,1,27,1,21102,1,915,0,1106,0,922,21201,1,51805,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,942,0,0,1106,0,922,22101,0,1,-1,21201,-2,-3,1,21101,0,957,0,1105,1,922,22201,1,-1,-2,1105,1,968,21201,-2,0,-2,109,-3,2105,1,0

56
2019/day09/main.go Normal file
View File

@ -0,0 +1,56 @@
package main
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"strings"
"time"
intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor"
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
progFileName := "input"
if len(os.Args) > 1 {
progFileName = os.Args[1]
}
dat, err := ioutil.ReadFile(progFileName)
if err != nil {
fmt.Println("Error reading program file:", err.Error())
os.Exit(1)
}
var prog []int
stringDat := strings.TrimSpace(string(dat))
for _, v := range strings.Split(stringDat, ",") {
prog = append(prog, helpers.Atoi(v))
}
part1(prog)
}
func part1(inp []int) {
p := intcode.NewProgram(inp)
//p.EnableDebug()
go p.Run()
for p.State() != intcode.RET_DONE {
if p.State() == intcode.RET_ERR {
panic(p.Error())
}
if p.NeedsInput() {
fmt.Print("Requesting Input: ")
reader := bufio.NewReader(os.Stdin)
inp, err := reader.ReadString('\n')
if err != nil {
fmt.Println("Input Error:", err.Error())
} else {
p.Input(helpers.Atoi(strings.TrimSpace(inp)))
}
}
if p.NeedsOutput() {
fmt.Println(p.Output())
}
time.Sleep(1)
}
}

1
2019/day09/testinput1 Normal file
View File

@ -0,0 +1 @@
109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99

1
2019/day09/testinput2 Normal file
View File

@ -0,0 +1 @@
1102,34915192,34915192,7,4,7,99,0

1
2019/day09/testinput3 Normal file
View File

@ -0,0 +1 @@
104,1125899906842624,99

View File

@ -15,12 +15,14 @@ const (
OP_JIF = 6 OP_JIF = 6
OP_ILT = 7 OP_ILT = 7
OP_IEQ = 8 OP_IEQ = 8
OP_RBS = 9
OP_EXT = 99 OP_EXT = 99
) )
const ( const (
MODE_POS = iota MODE_POS = iota
MODE_IMM MODE_IMM
MODE_REL
) )
const ( const (
@ -33,6 +35,7 @@ type Program struct {
originalCode []int originalCode []int
code []int code []int
ptr int ptr int
relBase int
state int state int
error error error error
@ -41,6 +44,8 @@ type Program struct {
input chan int input chan int
waitingForOutput bool waitingForOutput bool
output chan int output chan int
debug bool
} }
func NewProgram(prog []int) *Program { func NewProgram(prog []int) *Program {
@ -52,6 +57,20 @@ func NewProgram(prog []int) *Program {
return p return p
} }
func (p *Program) EnableDebug() {
p.debug = true
}
func (p *Program) DisableDebug() {
p.debug = false
}
func (p *Program) DebugLog(l string) {
if p.debug {
fmt.Print(l)
}
}
func (p *Program) Reset() { func (p *Program) Reset() {
copy(p.code, p.originalCode) copy(p.code, p.originalCode)
p.ptr = 0 p.ptr = 0
@ -61,6 +80,7 @@ func (p *Program) Reset() {
p.waitingForOutput = false p.waitingForOutput = false
p.input = make(chan int) p.input = make(chan int)
p.output = make(chan int) p.output = make(chan int)
p.relBase = 0
} }
func (p *Program) GetCode() []int { func (p *Program) GetCode() []int {
@ -89,11 +109,13 @@ func (p *Program) Step() int {
p.error = errors.New("Pointer Exception") p.error = errors.New("Pointer Exception")
return RET_ERR return RET_ERR
} }
p.DebugLog(p.String() + "\n")
intcode := p.readNext() intcode := p.readNext()
p.ptr++ p.ptr++
switch p.opCode(intcode) { switch p.opCode(intcode) {
case OP_ADD: case OP_ADD:
v1, v2, v3 := p.readNextThree() v1, v2, v3 := p.readNextThree()
p.DebugLog(fmt.Sprintf("ADD %d (%d, %d, %d)\n", intcode, v1, v2, v3))
p.ptr = p.ptr + 3 p.ptr = p.ptr + 3
p.opAdd(intcode, v1, v2, v3) p.opAdd(intcode, v1, v2, v3)
if p.error != nil { if p.error != nil {
@ -102,6 +124,7 @@ func (p *Program) Step() int {
return RET_OK return RET_OK
case OP_MLT: case OP_MLT:
v1, v2, v3 := p.readNextThree() v1, v2, v3 := p.readNextThree()
p.DebugLog(fmt.Sprintf("MLT %d (%d, %d, %d)\n", intcode, v1, v2, v3))
p.ptr = p.ptr + 3 p.ptr = p.ptr + 3
p.opMult(intcode, v1, v2, v3) p.opMult(intcode, v1, v2, v3)
if p.error != nil { if p.error != nil {
@ -110,6 +133,7 @@ func (p *Program) Step() int {
return RET_OK return RET_OK
case OP_INP: case OP_INP:
v1 := p.readNext() v1 := p.readNext()
p.DebugLog(fmt.Sprintf("INP %d (%d)\n", intcode, v1))
p.ptr++ p.ptr++
p.opInp(intcode, v1) p.opInp(intcode, v1)
if p.error != nil { if p.error != nil {
@ -119,6 +143,7 @@ func (p *Program) Step() int {
case OP_OUT: case OP_OUT:
v1 := p.readNext() v1 := p.readNext()
p.ptr++ p.ptr++
p.DebugLog(fmt.Sprintf("OUT %d (%d)\n", intcode, v1))
p.opOut(intcode, v1) p.opOut(intcode, v1)
if p.error != nil { if p.error != nil {
return RET_ERR return RET_ERR
@ -126,6 +151,7 @@ func (p *Program) Step() int {
return RET_OK return RET_OK
case OP_JIT: case OP_JIT:
v1, v2 := p.readNextTwo() v1, v2 := p.readNextTwo()
p.DebugLog(fmt.Sprintf("JIT %d (%d, %d)\n", intcode, v1, v2))
p.ptr = p.ptr + 2 p.ptr = p.ptr + 2
p.opJumpIfTrue(intcode, v1, v2) p.opJumpIfTrue(intcode, v1, v2)
if p.error != nil { if p.error != nil {
@ -134,6 +160,7 @@ func (p *Program) Step() int {
return RET_OK return RET_OK
case OP_JIF: case OP_JIF:
v1, v2 := p.readNextTwo() v1, v2 := p.readNextTwo()
p.DebugLog(fmt.Sprintf("JIF %d (%d, %d)\n", intcode, v1, v2))
p.ptr = p.ptr + 2 p.ptr = p.ptr + 2
p.opJumpIfFalse(intcode, v1, v2) p.opJumpIfFalse(intcode, v1, v2)
if p.error != nil { if p.error != nil {
@ -142,6 +169,7 @@ func (p *Program) Step() int {
return RET_OK return RET_OK
case OP_ILT: case OP_ILT:
v1, v2, dest := p.readNextThree() v1, v2, dest := p.readNextThree()
p.DebugLog(fmt.Sprintf("ILT %d (%d, %d, %d)\n", intcode, v1, v2, dest))
p.ptr = p.ptr + 3 p.ptr = p.ptr + 3
p.opIfLessThan(intcode, v1, v2, dest) p.opIfLessThan(intcode, v1, v2, dest)
if p.error != nil { if p.error != nil {
@ -150,24 +178,39 @@ func (p *Program) Step() int {
return RET_OK return RET_OK
case OP_IEQ: case OP_IEQ:
v1, v2, dest := p.readNextThree() v1, v2, dest := p.readNextThree()
p.DebugLog(fmt.Sprintf("IEQ %d (%d, %d, %d)\n", intcode, v1, v2, dest))
p.ptr = p.ptr + 3 p.ptr = p.ptr + 3
p.opIfEqual(intcode, v1, v2, dest) p.opIfEqual(intcode, v1, v2, dest)
if p.error != nil { if p.error != nil {
return RET_ERR return RET_ERR
} }
return RET_OK return RET_OK
case OP_RBS:
v1 := p.readNext()
p.DebugLog(fmt.Sprintf("RBS %d (%d)\n", intcode, v1))
p.ptr = p.ptr + 1
p.opModRelBase(intcode, v1)
if p.error != nil {
return RET_ERR
}
return RET_OK
case OP_EXT: case OP_EXT:
p.DebugLog(fmt.Sprintf("EXT %d\n", intcode))
return RET_DONE return RET_DONE
} }
p.error = errors.New(fmt.Sprintf("Invalid OpCode (%d)", intcode))
p.DebugLog(p.String())
return RET_ERR return RET_ERR
} }
func (p *Program) GetProgramValueAt(idx int) int { func (p *Program) GetProgramValueAt(idx int) int {
p.ensureLength(idx)
return p.code[idx] return p.code[idx]
} }
func (p *Program) SetProgramValueAt(idx, val int) { func (p *Program) SetProgramValueAt(idx, val int) {
p.ensureLength(idx)
p.code[idx] = val p.code[idx] = val
} }
@ -188,28 +231,48 @@ func (p *Program) paramMode(intcode, pNum int) int {
return ((intcode - p.opCode(intcode)) / int(plc)) % 10 return ((intcode - p.opCode(intcode)) / int(plc)) % 10
} }
func (p *Program) readNext() int { func (p *Program) ensureLength(idx int) {
if len(p.code) <= p.ptr { for len(p.code) < idx+1 {
p.error = errors.New("Pointer Exception") p.code = append(p.code, 0)
} }
}
func (p *Program) readNext() int {
p.ensureLength(p.ptr)
return p.code[p.ptr] return p.code[p.ptr]
} }
func (p *Program) readNextTwo() (int, int) { func (p *Program) readNextTwo() (int, int) {
p.ensureLength(p.ptr + 1)
return p.code[p.ptr], p.code[p.ptr+1] return p.code[p.ptr], p.code[p.ptr+1]
} }
func (p *Program) readNextThree() (int, int, int) { func (p *Program) readNextThree() (int, int, int) {
p.ensureLength(p.ptr + 2)
return p.code[p.ptr], p.code[p.ptr+1], p.code[p.ptr+2] return p.code[p.ptr], p.code[p.ptr+1], p.code[p.ptr+2]
} }
func (p *Program) get(mode, v int) int { func (p *Program) get(mode, v int) int {
if mode == MODE_POS { if mode == MODE_POS {
p.ensureLength(v)
return p.code[v] return p.code[v]
} else if mode == MODE_REL {
p.ensureLength(p.relBase + v)
return p.code[p.relBase+v]
} }
return v return v
} }
func (p *Program) set(mode, idx, v int) {
if mode == MODE_POS {
p.ensureLength(idx)
p.code[idx] = v
} else if mode == MODE_REL {
p.ensureLength(p.relBase + idx)
p.code[p.relBase+idx] = v
}
}
func (p *Program) Input(v int) { func (p *Program) Input(v int) {
p.input <- v p.input <- v
p.waitingForInput = false p.waitingForInput = false
@ -223,30 +286,18 @@ func (p *Program) Output() int {
func (p *Program) opAdd(intcode, a1, a2, dest int) { func (p *Program) opAdd(intcode, a1, a2, dest int) {
a1md, a2md, destmd := p.paramMode(intcode, 0), p.paramMode(intcode, 1), p.paramMode(intcode, 2) a1md, a2md, destmd := p.paramMode(intcode, 0), p.paramMode(intcode, 1), p.paramMode(intcode, 2)
if destmd != MODE_POS { p.set(destmd, dest, p.get(a1md, a1)+p.get(a2md, a2))
p.error = errors.New("Invalid Destination Mode")
p.state = RET_ERR
}
p.code[dest] = p.get(a1md, a1) + p.get(a2md, a2)
} }
func (p *Program) opMult(intcode, a1, a2, dest int) { func (p *Program) opMult(intcode, a1, a2, dest int) {
a1md, a2md, destmd := p.paramMode(intcode, 0), p.paramMode(intcode, 1), p.paramMode(intcode, 2) a1md, a2md, destmd := p.paramMode(intcode, 0), p.paramMode(intcode, 1), p.paramMode(intcode, 2)
if destmd != MODE_POS { p.set(destmd, dest, p.get(a1md, a1)*p.get(a2md, a2))
p.error = errors.New("Invalid Destination Mode")
p.state = RET_ERR
}
p.code[dest] = p.get(a1md, a1) * p.get(a2md, a2)
} }
func (p *Program) opInp(intcode, dest int) { func (p *Program) opInp(intcode, dest int) {
destmd := p.paramMode(intcode, 0) destmd := p.paramMode(intcode, 0)
if destmd != MODE_POS {
p.error = errors.New("Invalid Destination Mode")
p.state = RET_ERR
}
p.waitingForInput = true p.waitingForInput = true
p.code[dest] = <-p.input p.set(destmd, dest, <-p.input)
p.waitingForInput = false p.waitingForInput = false
} }
@ -273,32 +324,30 @@ func (p *Program) opJumpIfFalse(intcode, v1, v2 int) {
func (p *Program) opIfLessThan(intcode, v1, v2, dest int) { func (p *Program) opIfLessThan(intcode, v1, v2, dest int) {
v1md, v2md, destmd := p.paramMode(intcode, 0), p.paramMode(intcode, 1), p.paramMode(intcode, 2) v1md, v2md, destmd := p.paramMode(intcode, 0), p.paramMode(intcode, 1), p.paramMode(intcode, 2)
if destmd != MODE_POS {
p.error = errors.New("Invalid Destination Mode")
p.state = RET_ERR
}
if p.get(v1md, v1) < p.get(v2md, v2) { if p.get(v1md, v1) < p.get(v2md, v2) {
p.code[dest] = 1 p.set(destmd, dest, 1)
} else { } else {
p.code[dest] = 0 p.set(destmd, dest, 0)
} }
} }
func (p *Program) opIfEqual(intcode, v1, v2, dest int) { func (p *Program) opIfEqual(intcode, v1, v2, dest int) {
v1md, v2md, destmd := p.paramMode(intcode, 0), p.paramMode(intcode, 1), p.paramMode(intcode, 2) v1md, v2md, destmd := p.paramMode(intcode, 0), p.paramMode(intcode, 1), p.paramMode(intcode, 2)
if destmd != MODE_POS {
p.error = errors.New("Invalid Destination Mode")
p.state = RET_ERR
}
if p.get(v1md, v1) == p.get(v2md, v2) { if p.get(v1md, v1) == p.get(v2md, v2) {
p.code[dest] = 1 p.set(destmd, dest, 1)
} else { } else {
p.code[dest] = 0 p.set(destmd, dest, 0)
} }
} }
func (p *Program) opModRelBase(intcode, v1 int) {
v1md := p.paramMode(intcode, 0)
p.relBase = p.relBase + p.get(v1md, v1)
}
func (p Program) String() string { func (p Program) String() string {
var ret string var ret string
ret = ret + fmt.Sprintf("(PTR: %d, RBS: %d)\n", p.ptr, p.relBase)
for k := range p.code { for k := range p.code {
if k == p.ptr { if k == p.ptr {
ret = fmt.Sprintf("%s [%d]", ret, p.code[k]) ret = fmt.Sprintf("%s [%d]", ret, p.code[k])