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() fmt.Print(allPerms[k], ": ") wrk := pt1RunWithPhaseSettings(allPerms[k]) fmt.Println(wrk) if wrk > max { max = wrk bestPerm = allPerms[k] } } fmt.Println("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) 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() fmt.Print(allPerms[k], ": ") wrk := pt2RunWithPhaseSettings(allPerms[k]) fmt.Println(wrk) if wrk > max { max = wrk bestPerm = allPerms[k] } } fmt.Println("BEST: ", bestPerm, max) } func pt2RunWithPhaseSettings(settings []int) int { go func() { a1.Input(settings[0]) a2.Input(settings[1]) a3.Input(settings[2]) a4.Input(settings[3]) a5.Input(settings[4]) a1.Input(0) for { if a5.NeedsOutput() { a5Out := a5.Output() fmt.Println("A5: ", a5Out) a1.Input(a5Out) } a2.Input(a1.Output()) a3.Input(a2.Output()) a4.Input(a3.Output()) a5.Input(a4.Output()) if a5.State() == intcode.RET_DONE { break } for !a5.NeedsOutput() { time.Sleep(1) } } }() for a5.State() != intcode.RET_DONE && !a5.NeedsOutput() { time.Sleep(1) } return a5.Output() }