diff --git a/days/02.go b/days/02.go new file mode 100644 index 0000000..f34098d --- /dev/null +++ b/days/02.go @@ -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, + ) +} diff --git a/inputs/02p.txt b/inputs/02p.txt new file mode 100644 index 0000000..3f14cd0 --- /dev/null +++ b/inputs/02p.txt @@ -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 \ No newline at end of file diff --git a/main.go b/main.go index c7a6132..5e53843 100644 --- a/main.go +++ b/main.go @@ -26,6 +26,7 @@ const ( var dayMap = map[int]day{ 1: &days.Day01{}, + 2: &days.Day02{}, } func main() { diff --git a/utilities/intcode.go b/utilities/intcode.go new file mode 100644 index 0000000..abf1edc --- /dev/null +++ b/utilities/intcode.go @@ -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 + } + } +} diff --git a/utilities/parsing.go b/utilities/parsing.go index c7ae466..03b452e 100644 --- a/utilities/parsing.go +++ b/utilities/parsing.go @@ -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 { retval := make([]string, 0) getData(filename, func(line string) {