Working d8p2
This commit is contained in:
parent
a17153662e
commit
64de63ddbe
@ -4,6 +4,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
@ -18,6 +19,7 @@ type Nodes struct {
|
|||||||
rightN []int32
|
rightN []int32
|
||||||
index int
|
index int
|
||||||
steps uint64
|
steps uint64
|
||||||
|
allSteps []int
|
||||||
}
|
}
|
||||||
|
|
||||||
func check(e error) {
|
func check(e error) {
|
||||||
@ -31,6 +33,28 @@ func PrintAndWait(x ...any) {
|
|||||||
fmt.Scanln()
|
fmt.Scanln()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://siongui.github.io/2017/06/03/go-find-lcm-by-gcd/
|
||||||
|
// greatest common divisor (GCD) via Euclidean algorithm
|
||||||
|
func GCD(a, b int) int {
|
||||||
|
for b != 0 {
|
||||||
|
t := b
|
||||||
|
b = a % b
|
||||||
|
a = t
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// find Least Common Multiple (LCM) via GCD
|
||||||
|
func LCM(a, b int, integers ...int) int {
|
||||||
|
result := a * b / GCD(a, b)
|
||||||
|
|
||||||
|
for i := 0; i < len(integers); i++ {
|
||||||
|
result = LCM(result, integers[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func (n *Nodes) toByteSingle(s string) {
|
func (n *Nodes) toByteSingle(s string) {
|
||||||
// I've just received something like AAA
|
// I've just received something like AAA
|
||||||
var temp int32
|
var temp int32
|
||||||
@ -47,25 +71,71 @@ func (n *Nodes) toByteDuet(s, r string) {
|
|||||||
for i := len(s) - 1; i >= 0; i-- {
|
for i := len(s) - 1; i >= 0; i-- {
|
||||||
tempL += int32(s[i]) << ((len(s) - 1 - i) * 8)
|
tempL += int32(s[i]) << ((len(s) - 1 - i) * 8)
|
||||||
tempR += int32(r[i]) << ((len(s) - 1 - i) * 8)
|
tempR += int32(r[i]) << ((len(s) - 1 - i) * 8)
|
||||||
//fmt.Printf("Received %c (%b), now I have %b | ", s[i], s[i], tempL)
|
|
||||||
//fmt.Printf("Received %c (%b), now I have %b\n", r[i], r[i], tempR)
|
|
||||||
//fmt.Scanln()
|
|
||||||
}
|
}
|
||||||
n.leftN = append(n.leftN, tempL)
|
n.leftN = append(n.leftN, tempL)
|
||||||
n.rightN = append(n.rightN, tempR)
|
n.rightN = append(n.rightN, tempR)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Nodes) findNext(myN int32) {
|
func (n *Nodes) findNext(myN int32) int {
|
||||||
//var wg sync.WaitGroup
|
//var wg sync.WaitGroup
|
||||||
|
ind := 0
|
||||||
for i := 0; i < len(n.singleN); i++ {
|
for i := 0; i < len(n.singleN); i++ {
|
||||||
if myN^n.singleN[i] == 0 {
|
if myN^n.singleN[i] == 0 {
|
||||||
|
n.mu.Lock()
|
||||||
n.index = i
|
n.index = i
|
||||||
|
n.mu.Unlock()
|
||||||
|
ind = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ind
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Nodes) findAll(ind int, sp []int, wg *sync.WaitGroup) {
|
||||||
|
index := 0
|
||||||
|
// We only go from the start
|
||||||
|
matching := n.rightN[sp[ind]]
|
||||||
|
if n.commands[0]^LEFT == 0 {
|
||||||
|
matching = n.leftN[sp[ind]]
|
||||||
|
}
|
||||||
|
index = n.findNext(matching)
|
||||||
|
n.allSteps[ind]++
|
||||||
|
i := 0
|
||||||
|
for {
|
||||||
|
// Every step is in a single direction. For every step, we may need to
|
||||||
|
// scan len(n.singleN) elements.
|
||||||
|
// Circular loop
|
||||||
|
index = n.findNext(matching)
|
||||||
|
// Increment i after finding the match
|
||||||
|
i++
|
||||||
|
i = i % len(n.commands)
|
||||||
|
// By default, we will assume we are on the right
|
||||||
|
matching = n.rightN[index]
|
||||||
|
//PrintAndWait()
|
||||||
|
// If we are not, we are in the left
|
||||||
|
if n.commands[i]^LEFT == 0 {
|
||||||
|
matching = n.leftN[index]
|
||||||
|
}
|
||||||
|
n.allSteps[ind]++
|
||||||
|
// If we find XXZ, end
|
||||||
|
temp := matching & 255
|
||||||
|
if temp ^ 'Z' == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//fmt.Printf("I started from %d, matched at %d, taking %d steps.\n", sp[ind], index, n.allSteps[ind] )
|
||||||
|
wg.Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
func timer(name string) func() {
|
||||||
|
start := time.Now()
|
||||||
|
return func() {
|
||||||
|
fmt.Printf("%s took %v\n", name, time.Since(start))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
defer timer ("main")()
|
||||||
file, err := os.Open("./inputs/day08_input")
|
file, err := os.Open("./inputs/day08_input")
|
||||||
check(err)
|
check(err)
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
@ -136,4 +206,28 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Printf("\nSteps: %d\n", n.steps)
|
fmt.Printf("\nSteps: %d\n", n.steps)
|
||||||
|
// Now, for the main event
|
||||||
|
// Let's get ready to rumble
|
||||||
|
startPoints := make([]int, 0)
|
||||||
|
for i := 0; i < len(n.singleN); i++ {
|
||||||
|
// Lets remove all bytes except last 8
|
||||||
|
temp := n.singleN[i] & 255
|
||||||
|
if (temp ^ 'A') == 0 {
|
||||||
|
startPoints = append(startPoints, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now, from the starting points, we should go and match until
|
||||||
|
// we find a path that ends in Z
|
||||||
|
n.allSteps = make([]int, len(startPoints))
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for i := 0; i < len(startPoints); i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go n.findAll(i, startPoints, &wg)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
result := 1
|
||||||
|
for i := 0; i < len(n.allSteps); i++ {
|
||||||
|
result = LCM(result, n.allSteps[i])
|
||||||
|
}
|
||||||
|
fmt.Printf("Steps: %d\n", result)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user