Files
adventofcode/2023/go/day08/day08.go
2023-12-13 23:54:55 +00:00

101 lines
2.1 KiB
Go

package day08
import (
"fmt"
_ "adventofcode2023/utils"
"regexp"
"strings"
"math"
)
type Node struct {
left string
right string
}
type Network map[string]Node
func Part1(input string) int {
instructions, network := parseInput(input)
return getSteps("AAA", instructions, network, true)
}
func Part2(input string) int {
instructions, nexts, network := parseInput2(input)
fmt.Println(nexts)
ans := 1
for _, next := range nexts {
ans = lcm(ans, getSteps(next, instructions, network, false))
}
return ans
}
// gcd calculates the greatest common divisor using Euclid's algorithm
func gcd(a, b int) int {
for b != 0 {
a, b = b, a%b
}
return a
}
// lcm calculates the least common multiple using the formula: LCM(a, b) = |a * b| / GCD(a, b)
func lcm(a, b int) int {
if a == 0 || b == 0 {
return 0
}
return int(math.Abs(float64(a*b)) / float64(gcd(a, b)))
}
func parseInput(input string) ([]rune, Network) {
network := make(Network)
lines := strings.Split(input, "\n")
instructions := []rune(lines[0])
re := regexp.MustCompile(`(\w+) = \((\w+), (\w+)\)`)
for _, line := range lines[2:] {
matches := re.FindAllStringSubmatch(line, -1)
network[matches[0][1]] = Node{matches[0][2], matches[0][3]}
}
return instructions, network
}
func parseInput2(input string) ([]rune, []string, Network) {
network := make(Network)
lines := strings.Split(input, "\n")
start := []string{}
instructions := []rune(lines[0])
re := regexp.MustCompile(`(\w+) = \((\w+), (\w+)\)`)
for _, line := range lines[2:] {
matches := re.FindAllStringSubmatch(line, -1)
network[matches[0][1]] = Node{matches[0][2], matches[0][3]}
if matches[0][1][2] == 'A' {
start = append(start, matches[0][1])
}
}
return instructions, start, network
}
func getSteps(next string, instructions []rune, network Network, partOne bool) int{
steps := 0
for {
for _, ins := range instructions {
steps++
if ins == 'L' {
next = network[next].left
} else {
next = network[next].right
}
if partOne {
if next == "ZZZ" {
return steps
}
} else {
if next[2] == 'Z' {
fmt.Println(next)
return steps
}
}
}
}
}