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 }