adventofcode/2019/day07/main.go
2019-12-09 09:17:27 -06:00

138 lines
2.7 KiB
Go

package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
"time"
intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor"
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)
var a1, a2, a3, a4, a5 *intcode.Program
func main() {
progFileName := "input"
if len(os.Args) > 1 {
progFileName = os.Args[1]
}
dat, err := ioutil.ReadFile(progFileName)
if err != nil {
fmt.Println("Error reading program file:", err.Error())
os.Exit(1)
}
var prog []int
stringDat := strings.TrimSpace(string(dat))
for _, v := range strings.Split(stringDat, ",") {
prog = append(prog, helpers.Atoi(v))
}
part1(prog)
part2(prog)
}
func part1(prog []int) {
allPerms := helpers.IntPermutations([]int{0, 1, 2, 3, 4})
var bestPerm []int
max := 0
for k := range allPerms {
a1 = intcode.NewProgram(prog)
go a1.Run()
a2 = intcode.NewProgram(prog)
go a2.Run()
a3 = intcode.NewProgram(prog)
go a3.Run()
a4 = intcode.NewProgram(prog)
go a4.Run()
a5 = intcode.NewProgram(prog)
go a5.Run()
wrk := pt1RunWithPhaseSettings(allPerms[k])
if wrk > max {
max = wrk
bestPerm = allPerms[k]
}
}
fmt.Println("Part 1 BEST: ", bestPerm, max)
}
func pt1RunWithPhaseSettings(settings []int) int {
go func() {
a1.Input(settings[0])
a1.Input(0)
a2.Input(settings[1])
a2.Input(a1.Output())
a3.Input(settings[2])
a3.Input(a2.Output())
a4.Input(settings[3])
a4.Input(a3.Output())
a5.Input(settings[4])
a5.Input(a4.Output())
}()
for !a5.NeedsOutput() {
time.Sleep(1)
}
return a5.Output()
}
func part2(prog []int) {
allPerms := helpers.IntPermutations([]int{5, 6, 7, 8, 9})
var bestPerm []int
max := 0
for k := range allPerms {
a1 = intcode.NewProgram(prog)
a1.Reset()
go a1.Run()
a2 = intcode.NewProgram(prog)
a2.Reset()
go a2.Run()
a3 = intcode.NewProgram(prog)
a3.Reset()
go a3.Run()
a4 = intcode.NewProgram(prog)
a4.Reset()
go a4.Run()
a5 = intcode.NewProgram(prog)
a5.Reset()
go a5.Run()
wrk := pt2RunWithPhaseSettings(allPerms[k])
if wrk > max {
max = wrk
bestPerm = allPerms[k]
}
}
fmt.Println("Part 2 BEST: ", bestPerm, max)
}
func pt2RunWithPhaseSettings(settings []int) int {
a1.Input(settings[0])
a2.Input(settings[1])
a3.Input(settings[2])
a4.Input(settings[3])
a5.Input(settings[4])
a5Out := 0
for {
a1.Input(a5Out)
a2.Input(a1.Output())
a3.Input(a2.Output())
a4.Input(a3.Output())
a5.Input(a4.Output())
for !a5.NeedsOutput() {
time.Sleep(1)
}
a5Out = a5.Output()
// Wait until amp 5 is either done, or waiting
for a5.State() != intcode.RET_DONE && !a5.NeedsInput() {
time.Sleep(1)
}
if a5.State() == intcode.RET_DONE {
break
}
}
return a5Out
}