Day 2 initial solution
There's room to optimize part 2, but I wanted to commit my original brute-force solution first.
This commit is contained in:
70
days/02.go
Normal file
70
days/02.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package days
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"parnic.com/aoc2019/utilities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Day02 struct {
|
||||||
|
program []int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day02) Parse() {
|
||||||
|
d.program = utilities.ParseIntcodeProgram(utilities.GetStringContents("02p"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day02) Num() int {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day02) getProgramWithParams(param1, param2 int64) []int64 {
|
||||||
|
program := make([]int64, len(d.program))
|
||||||
|
copy(program, d.program)
|
||||||
|
program[1] = param1
|
||||||
|
program[2] = param2
|
||||||
|
return program
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day02) Part1() string {
|
||||||
|
program := d.getProgramWithParams(12, 2)
|
||||||
|
utilities.RunIntcodeProgram(program)
|
||||||
|
|
||||||
|
return fmt.Sprintf("Position 0 = %s%d%s", utilities.TextBold, program[0], utilities.TextReset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day02) Part2() string {
|
||||||
|
sentinel := int64(19690720)
|
||||||
|
|
||||||
|
var noun int64
|
||||||
|
var verb int64
|
||||||
|
found := false
|
||||||
|
for noun = 0; noun <= 99; noun++ {
|
||||||
|
for verb = 0; verb <= 99; verb++ {
|
||||||
|
program := d.getProgramWithParams(noun, verb)
|
||||||
|
utilities.RunIntcodeProgram(program)
|
||||||
|
|
||||||
|
if program[0] == sentinel {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
panic("!found")
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%d created by noun=%d, verb=%d. 100 * noun + verb = %s%d%s",
|
||||||
|
sentinel,
|
||||||
|
noun,
|
||||||
|
verb,
|
||||||
|
utilities.TextBold,
|
||||||
|
100*noun+verb,
|
||||||
|
utilities.TextReset,
|
||||||
|
)
|
||||||
|
}
|
1
inputs/02p.txt
Normal file
1
inputs/02p.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,10,1,19,1,19,9,23,1,23,6,27,1,9,27,31,1,31,10,35,2,13,35,39,1,39,10,43,1,43,9,47,1,47,13,51,1,51,13,55,2,55,6,59,1,59,5,63,2,10,63,67,1,67,9,71,1,71,13,75,1,6,75,79,1,10,79,83,2,9,83,87,1,87,5,91,2,91,9,95,1,6,95,99,1,99,5,103,2,103,10,107,1,107,6,111,2,9,111,115,2,9,115,119,2,13,119,123,1,123,9,127,1,5,127,131,1,131,2,135,1,135,6,0,99,2,0,14,0
|
1
main.go
1
main.go
@ -26,6 +26,7 @@ const (
|
|||||||
|
|
||||||
var dayMap = map[int]day{
|
var dayMap = map[int]day{
|
||||||
1: &days.Day01{},
|
1: &days.Day01{},
|
||||||
|
2: &days.Day02{},
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
47
utilities/intcode.go
Normal file
47
utilities/intcode.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package utilities
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ParseIntcodeProgram(programStr string) []int64 {
|
||||||
|
nums := strings.Split(programStr, ",")
|
||||||
|
program := make([]int64, len(nums))
|
||||||
|
for idx, num := range nums {
|
||||||
|
iNum, err := strconv.ParseInt(num, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
program[idx] = iNum
|
||||||
|
}
|
||||||
|
|
||||||
|
return program
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunIntcodeProgram(program []int64) {
|
||||||
|
for instructionPointer := 0; instructionPointer < len(program); {
|
||||||
|
opcode := program[instructionPointer]
|
||||||
|
switch opcode {
|
||||||
|
case 1:
|
||||||
|
param1 := program[instructionPointer+1]
|
||||||
|
param2 := program[instructionPointer+2]
|
||||||
|
param3 := program[instructionPointer+3]
|
||||||
|
program[param3] = program[param1] + program[param2]
|
||||||
|
|
||||||
|
instructionPointer += 4
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
param1 := program[instructionPointer+1]
|
||||||
|
param2 := program[instructionPointer+2]
|
||||||
|
param3 := program[instructionPointer+3]
|
||||||
|
program[param3] = program[param1] * program[param2]
|
||||||
|
|
||||||
|
instructionPointer += 4
|
||||||
|
break
|
||||||
|
case 99:
|
||||||
|
instructionPointer = len(program)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,17 @@ func getData(filename string, lineHandler func(line string)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetStringContents(filename string) string {
|
||||||
|
var retval string
|
||||||
|
getData(filename, func(line string) {
|
||||||
|
if len(retval) != 0 {
|
||||||
|
panic("tried to parse multi-line file as a single line")
|
||||||
|
}
|
||||||
|
retval = line
|
||||||
|
})
|
||||||
|
return retval
|
||||||
|
}
|
||||||
|
|
||||||
func GetStringLines(filename string) []string {
|
func GetStringLines(filename string) []string {
|
||||||
retval := make([]string, 0)
|
retval := make([]string, 0)
|
||||||
getData(filename, func(line string) {
|
getData(filename, func(line string) {
|
||||||
|
Reference in New Issue
Block a user