adventofcode/2019/day02/main.go

150 lines
3.1 KiB
Go

package main
import (
"bufio"
"fmt"
intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor"
"log"
"os"
"strconv"
"strings"
)
func main() {
inp := StdinToString()
var prog []int
for _, v := range strings.Split(inp, ",") {
prog = append(prog, Atoi(v))
}
part1(prog)
part2(prog)
}
func part1(prog []int) {
p := intcode.NewProgram(prog)
p.Run()
if p.State() == intcode.RET_ERR {
fmt.Println(p.Error())
}
fmt.Println("Part 1:", p.GetProgramValueAt(0))
}
func part2(prog []int) {
runProg := func(n, v int, prog []int) int {
progcpy := make([]int, len(prog))
copy(progcpy, prog)
progcpy[1] = n
progcpy[2] = v
p := intcode.NewProgram(progcpy)
p.Run()
return p.GetProgramValueAt(0)
}
target := 19690720
zeroVal := runProg(0, 0, prog)
nDiff := runProg(1, 0, prog) - zeroVal
vDiff := runProg(0, 1, prog) - zeroVal
fmt.Println("Part 2:", ((target - zeroVal) / nDiff), ((target%nDiff)-(zeroVal%nDiff))/vDiff)
}
func slowestPart2(prog []int) {
for n := 0; n <= 99; n++ {
for v := 0; v <= 99; v++ {
progcpy := make([]int, len(prog))
copy(progcpy, prog)
progcpy[1], progcpy[2] = n, v
for i := 0; i < len(progcpy); i += 4 {
switch progcpy[i] {
case 1:
progcpy[progcpy[i+3]] = add(progcpy[i+1], progcpy[i+2], progcpy)
case 2:
progcpy[progcpy[i+3]] = mult(progcpy[i+1], progcpy[i+2], progcpy)
case 99:
if progcpy[0] == 19690720 {
fmt.Println("Found value:", n, v)
fmt.Println("Answer:", (100*n + v))
os.Exit(0)
} else {
fmt.Println(n, v, ":", progcpy[0])
}
i = len(progcpy)
}
}
}
}
}
func slowPart2(prog []int) {
target := 19690720
useN := 0
for n := 0; n <= 99; n++ {
progcpy := make([]int, len(prog))
copy(progcpy, prog)
progcpy[1] = n
for i := 0; i < len(progcpy); i += 4 {
switch progcpy[i] {
case 1:
progcpy[progcpy[i+3]] = add(progcpy[i+1], progcpy[i+2], progcpy)
case 2:
progcpy[progcpy[i+3]] = mult(progcpy[i+1], progcpy[i+2], progcpy)
case 99:
i = len(progcpy)
}
}
if progcpy[0] > target {
useN = n - 1
break
}
}
for v := 0; v <= 99; v++ {
progcpy := make([]int, len(prog))
copy(progcpy, prog)
progcpy[1] = useN
progcpy[2] = v
for i := 0; i < len(progcpy); i += 4 {
switch progcpy[i] {
case 1:
progcpy[progcpy[i+3]] = add(progcpy[i+1], progcpy[i+2], progcpy)
case 2:
progcpy[progcpy[i+3]] = mult(progcpy[i+1], progcpy[i+2], progcpy)
case 99:
if progcpy[0] == target {
fmt.Println("Found value:", useN, v)
fmt.Println("Answer:", (100*useN + v))
os.Exit(0)
}
i = len(progcpy)
}
}
}
}
func printState(prog []int) {
fmt.Println(prog)
}
func add(i, j int, prog []int) int {
return prog[i] + prog[j]
}
func mult(i, j int, prog []int) int {
return prog[i] * prog[j]
}
func StdinToString() string {
var input string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input += scanner.Text()
}
return input
}
func Atoi(i string) int {
var ret int
var err error
if ret, err = strconv.Atoi(i); err != nil {
log.Fatal("Invalid Atoi")
}
return ret
}