11package main
22
33import (
4- "aocli/utils"
54 _ "embed"
65 "os"
7- "strings"
86)
97
108//go:embed input.txt
@@ -26,51 +24,76 @@ func main() {
2624 println (answer )
2725}
2826
29- type Maps map [rune ]map [string ]string
27+ type Node struct {
28+ left string
29+ right string
30+ }
3031
31- func solve (input string , suffix string ) int {
32- lines := strings .Split (strings .TrimSpace (input ), "\n \n " )
33- instr := []rune (lines [0 ])
34- maps := buildMaps (lines [1 ])
35- P := []string {}
36- for p := range maps ['L' ] {
37- if strings .HasSuffix (p , suffix ) {
38- P = append (P , p )
39- }
40- }
32+ var (
33+ instructions string
34+ network map [string ]Node
35+ startNodes []string
36+ )
4137
42- I := [] int {}
38+ func parseInput ( input string ) {
4339 i := 0
44- for {
45- NP := []string {}
46- for _ , p := range P {
47- p = maps [instr [i % len (instr )]][p ]
48- if strings .HasSuffix (p , "Z" ) {
49- I = append (I , i + 1 )
50- if len (I ) == len (P ) {
51- return utils .LCM (1 , I [0 ], I [1 :]... )
52- }
53- }
54- NP = append (NP , p )
55- }
56- P = NP
40+ // Skip whitespace
41+ for i < len (input ) && (input [i ] == ' ' || input [i ] == '\n' || input [i ] == '\r' ) {
42+ i ++
43+ }
44+
45+ // Parse instructions
46+ start := i
47+ for i < len (input ) && input [i ] != '\n' {
48+ i ++
49+ }
50+ instructions = input [start :i ]
51+
52+ // Skip blank lines
53+ for i < len (input ) && (input [i ] == '\n' || input [i ] == '\r' ) {
5754 i ++
5855 }
56+
57+ // Parse network
58+ network = make (map [string ]Node )
59+ startNodes = make ([]string , 0 , 6 )
60+
61+ for i < len (input ) {
62+ if input [i ] == '\n' || input [i ] == '\r' {
63+ i ++
64+ continue
65+ }
66+
67+ // Parse: "AAA = (BBB, CCC)"
68+ name := input [i : i + 3 ]
69+ i += 7 // Skip " = ("
70+ left := input [i : i + 3 ]
71+ i += 5 // Skip ", "
72+ right := input [i : i + 3 ]
73+ i += 4 // Skip ")\n"
74+
75+ network [name ] = Node {left : left , right : right }
76+ if name [2 ] == 'A' {
77+ startNodes = append (startNodes , name )
78+ }
79+ }
80+ }
81+
82+ func gcd (a , b int ) int {
83+ for b != 0 {
84+ a , b = b , a % b
85+ }
86+ return a
87+ }
88+
89+ func lcm (a , b int ) int {
90+ return a * b / gcd (a , b )
5991}
6092
61- func buildMaps (line string ) Maps {
62- lines := strings .Split (line , "\n " )
63- maps := make (map [rune ]map [string ]string , 2 )
64- maps ['L' ] = make (map [string ]string , len (lines ))
65- maps ['R' ] = make (map [string ]string , len (lines ))
66- for _ , line := range lines {
67- s := strings .Split (line , " = " )
68- I := s [0 ]
69- lr := strings .Split (s [1 ], ", " )
70- L := lr [0 ][1 :]
71- R := lr [1 ][:3 ]
72- maps ['L' ][I ] = L
73- maps ['R' ][I ] = R
93+ func lcmSlice (nums []int ) int {
94+ result := nums [0 ]
95+ for i := 1 ; i < len (nums ); i ++ {
96+ result = lcm (result , nums [i ])
7497 }
75- return maps
98+ return result
7699}
0 commit comments