mirror of
https://github.com/Luzifer/aoc2019.git
synced 2024-12-22 14:01:17 +00:00
Add solution for Day 2
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
54c685022f
commit
9b67f2728c
3 changed files with 169 additions and 0 deletions
121
day02.go
Normal file
121
day02.go
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
package aoc2019
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseDay02Intcode(code string) ([]int, error) {
|
||||||
|
parts := strings.Split(code, ",")
|
||||||
|
|
||||||
|
var out []int
|
||||||
|
for _, n := range parts {
|
||||||
|
v, err := strconv.Atoi(n)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out = append(out, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeDay02Intcode(code []int) ([]int, error) {
|
||||||
|
var (
|
||||||
|
pos int
|
||||||
|
run = true
|
||||||
|
)
|
||||||
|
|
||||||
|
for run {
|
||||||
|
if pos >= len(code) {
|
||||||
|
return nil, errors.Errorf("Code position out of bounds: %d (len=%d)", pos, len(code))
|
||||||
|
}
|
||||||
|
|
||||||
|
switch code[pos] {
|
||||||
|
case 1:
|
||||||
|
// addition
|
||||||
|
p1, p2, pt := code[pos+1], code[pos+2], code[pos+3]
|
||||||
|
code[pt] = code[p1] + code[p2]
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
// multiplication
|
||||||
|
p1, p2, pt := code[pos+1], code[pos+2], code[pos+3]
|
||||||
|
code[pt] = code[p1] * code[p2]
|
||||||
|
|
||||||
|
case 99:
|
||||||
|
// program finished
|
||||||
|
run = false
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, errors.Errorf("Encountered invalid operation %d", code[pos])
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 4
|
||||||
|
}
|
||||||
|
|
||||||
|
return code, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func solveDay2Part1(inFile string) (int, error) {
|
||||||
|
raw, err := ioutil.ReadFile(inFile)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "Unable to read input")
|
||||||
|
}
|
||||||
|
|
||||||
|
code, err := parseDay02Intcode(strings.TrimSpace(string(raw)))
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "Unable to parse Intcode")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify data for "1202 program alarm"
|
||||||
|
code[1] = 12
|
||||||
|
code[2] = 2
|
||||||
|
|
||||||
|
// Execute Intcode
|
||||||
|
code, err = executeDay02Intcode(code)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "Unable to execute Intcode")
|
||||||
|
}
|
||||||
|
|
||||||
|
return code[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func solveDay2Part2(inFile string) (int, error) {
|
||||||
|
raw, err := ioutil.ReadFile(inFile)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "Unable to read input")
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedResult int = 19690720
|
||||||
|
|
||||||
|
for noun := 0; noun < 100; noun++ {
|
||||||
|
for verb := 0; verb < 100; verb++ {
|
||||||
|
|
||||||
|
// Re-initialize "memory"
|
||||||
|
code, err := parseDay02Intcode(strings.TrimSpace(string(raw)))
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "Unable to parse Intcode")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify code
|
||||||
|
code[1] = noun
|
||||||
|
code[2] = verb
|
||||||
|
|
||||||
|
// Execute Intcode
|
||||||
|
code, err = executeDay02Intcode(code)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "Unable to execute Intcode")
|
||||||
|
}
|
||||||
|
|
||||||
|
if code[0] == expectedResult {
|
||||||
|
return 100*noun + verb, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, errors.New("No valid result was found")
|
||||||
|
}
|
1
day02_input.txt
Normal file
1
day02_input.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,10,19,2,9,19,23,1,9,23,27,2,27,9,31,1,31,5,35,2,35,9,39,1,39,10,43,2,43,13,47,1,47,6,51,2,51,10,55,1,9,55,59,2,6,59,63,1,63,6,67,1,67,10,71,1,71,10,75,2,9,75,79,1,5,79,83,2,9,83,87,1,87,9,91,2,91,13,95,1,95,9,99,1,99,6,103,2,103,6,107,1,107,5,111,1,13,111,115,2,115,6,119,1,119,5,123,1,2,123,127,1,6,127,0,99,2,14,0,0
|
47
day02_test.go
Normal file
47
day02_test.go
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package aoc2019
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExecuteDay02Intcode(t *testing.T) {
|
||||||
|
for codeStr, expResult := range map[string][]int{
|
||||||
|
"1,0,0,0,99": {2, 0, 0, 0, 99},
|
||||||
|
"2,3,0,3,99": {2, 3, 0, 6, 99},
|
||||||
|
"2,4,4,5,99,0": {2, 4, 4, 5, 99, 9801},
|
||||||
|
"1,1,1,4,99,5,6,0,99": {30, 1, 1, 4, 2, 5, 6, 0, 99},
|
||||||
|
} {
|
||||||
|
code, err := parseDay02Intcode(codeStr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Parsing Intcode failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := executeDay02Intcode(code)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Intcode execution failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(res, expResult) {
|
||||||
|
t.Errorf("Intcode execution yield unexpected result: %+v != %+v", res, expResult)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCalculateDay2_Part1(t *testing.T) {
|
||||||
|
codeP0, err := solveDay2Part1("day02_input.txt")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Day 2 solver failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Solution Day 2 Part 1: %d", codeP0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCalculateDay2_Part2(t *testing.T) {
|
||||||
|
result, err := solveDay2Part2("day02_input.txt")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Day 2 solver failed: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Solution Day 2 Part 2: %d", result)
|
||||||
|
}
|
Loading…
Reference in a new issue