118 lines
2.1 KiB
Go
118 lines
2.1 KiB
Go
|
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
|
||
|
}
|