package main import ( "fmt" "os" "strings" "log" "strconv" "time" ) var aFact, bFact int var doPart1, judgeIsDone bool var score int func main() { var doPart1 bool // My input aStart := 679 bStart := 771 for i := range os.Args { if strings.HasPrefix(os.Args[i], "-a") { pts := strings.Split(os.Args[i], "=") if len(pts) == 2 { aStart = Atoi(pts[1]) } } else if strings.HasPrefix(os.Args[i], "-b") { pts := strings.Split(os.Args[i], "=") if len(pts) == 2 { bStart = Atoi(pts[1]) } } if os.Args[i] == "-test" { aStart = 65 bStart = 8921 } if os.Args[i] == "-1" { doPart1 = true } } aFact = 16807 bFact = 48271 if doPart1 { solve(aStart, 1, bStart, 1, 40000000) } else { solve(aStart, 4, bStart, 8, 5000000) } } func solve(aStart, aMod, bStart, bMod, target int) { fmt.Println("= Part 2 =") fmt.Print("(A ",aStart,"; B ",bStart,")\n") judgeChanA := make(chan int) judgeChanB := make(chan int) // The Judge Process go judgeWork(target, judgeChanA, judgeChanB) // Generator A Process go genWork(aStart, aFact, aMod, judgeChanA) // Generator B Process go genWork(bStart, bFact, bMod, judgeChanB) // Wait for the judge to say he's done for !judgeIsDone { time.Sleep(500) } fmt.Println("\nFinal",score) } func judgeWork(target int, judgeChanA, judgeChanB chan int) { for i := 0; i < target; i++ { aVal := <-judgeChanA bVal := <-judgeChanB if i % (target / 25) == 0 { fmt.Print(".") } if judge(aVal, bVal) { score++ } } judgeIsDone = true } func genWork(start, fact, mod int, judgeChan chan int) { for !judgeIsDone { start = getNextVal(start, fact) if start % mod == 0 { judgeChan <- start } } } func getNextVal(prev, fact int) int { return (prev * fact) % 2147483647 } func judge(aVal, bVal int) bool { aBin, bBin := GetBinaryString(aVal), GetBinaryString(bVal) return aBin[len(aBin)-16:] == bBin[len(bBin)-16:] } func GetBinaryString(inp int) string { return fmt.Sprintf("%032b", inp) } 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 }