diff --git a/day-8/go.mod b/day-8/go.mod new file mode 100644 index 0000000..e9a42c2 --- /dev/null +++ b/day-8/go.mod @@ -0,0 +1,3 @@ +module github.com/onyx-and-iris/aoc2023/day-8 + +go 1.20 diff --git a/day-8/one.go b/day-8/one.go new file mode 100644 index 0000000..94186ab --- /dev/null +++ b/day-8/one.go @@ -0,0 +1,28 @@ +package main + +const ( + LEFT = iota // 0 + RIGHT +) + +var directions string +var steps = map[string][]string{} + +// one returns the number of steps to reach 'ZZZ' +func one(lines []string) int { + parselines(lines) + + num := 0 + for i, step := 0, "AAA"; step != "ZZZ"; i, num = i+1, num+1 { + if i == len(directions) { + i = 0 + } + if directions[i] == 'L' { + step = steps[step][LEFT] + } else { + step = steps[step][RIGHT] + } + } + + return num +} diff --git a/day-8/run.sh b/day-8/run.sh new file mode 100755 index 0000000..3f6776a --- /dev/null +++ b/day-8/run.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +INPUT="input.txt" + +cat $INPUT | go run . \ No newline at end of file diff --git a/day-8/solution.go b/day-8/solution.go new file mode 100644 index 0000000..926f1d4 --- /dev/null +++ b/day-8/solution.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + + log "github.com/sirupsen/logrus" +) + +func init() { + log.SetLevel(log.InfoLevel) +} + +func main() { + lines := readlines() + + ans := one(lines) + fmt.Printf("solution one: %d\n", ans) + + ans = two(lines) + fmt.Printf("solution two: %d\n", ans) +} diff --git a/day-8/two.go b/day-8/two.go new file mode 100644 index 0000000..2c33b7f --- /dev/null +++ b/day-8/two.go @@ -0,0 +1,59 @@ +package main + +import ( + "strings" +) + +// GCF returns the greatest common factor of two numbers +func GCF(a, b int) int { + for b != 0 { + t := b + b = a % b + a = t + } + return a +} + +// LCM returns least common multiple of a set a numbers +func LCM(a, b int, integers ...int) int { + result := a * b / GCF(a, b) + + for i := 0; i < len(integers); i++ { + result = LCM(result, integers[i]) + } + + return result +} + +// two returns minimum steps required until all routes end with '*Z' +func two(lines []string) int { + parselines(lines) + + startpoints := make([]string, 0) + for k := range steps { + if strings.HasSuffix(k, "A") { + startpoints = append(startpoints, k) + } + } + + nums := []int{} + for _, step := range startpoints { + num := 0 + for i := 0; !strings.HasSuffix(step, "Z"); i, num = i+1, num+1 { + if i == len(directions) { + i = 0 + } + if directions[i] == 'L' { + step = steps[step][LEFT] + } else { + step = steps[step][RIGHT] + } + } + nums = append(nums, num) + } + + lcm := 0 + lcm = LCM(nums[0], nums[1], nums[2:]...) + + return lcm +} diff --git a/day-8/util.go b/day-8/util.go new file mode 100644 index 0000000..614dc3d --- /dev/null +++ b/day-8/util.go @@ -0,0 +1,39 @@ +package main + +import ( + "bufio" + "log" + "os" + "regexp" +) + +// readlines reads lines from stdin. +// returns input as an array of strings +func readlines() []string { + lines := []string{} + + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + + if err := scanner.Err(); err != nil { + log.Fatal(err) + } + + return lines +} + +var r = regexp.MustCompile(`(?P[A-Z0-9]{3}) = \((?P[A-Z0-9]{3}), (?P[A-Z0-9]{3})\)`) + +func parselines(lines []string) { + directions = lines[0] + + steps = make(map[string][]string, len(lines[2:])) + for _, line := range lines[2:] { + m := r.FindStringSubmatch(line) + if len(m) > 0 { + steps[m[1]] = []string{m[2], m[3]} + } + } +}