From cc6a0942fb606a80f68e8ce4a5fbc87d9d40a684 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Mon, 11 Dec 2023 18:41:46 +0000 Subject: [PATCH] day-11 --- day-11/go.mod | 8 +++++ day-11/go.sum | 4 +++ day-11/one.go | 87 ++++++++++++++++++++++++++++++++++++++++++++++ day-11/solution.go | 21 +++++++++++ day-11/two.go | 20 +++++++++++ day-11/util.go | 82 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 222 insertions(+) create mode 100644 day-11/go.mod create mode 100644 day-11/go.sum create mode 100644 day-11/one.go create mode 100644 day-11/solution.go create mode 100644 day-11/two.go create mode 100644 day-11/util.go diff --git a/day-11/go.mod b/day-11/go.mod new file mode 100644 index 0000000..aea2572 --- /dev/null +++ b/day-11/go.mod @@ -0,0 +1,8 @@ +module github.com/onyx-and-iris/aoc2023/day-11 + +go 1.21.5 + +require ( + github.com/samber/lo v1.39.0 // indirect + golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect +) diff --git a/day-11/go.sum b/day-11/go.sum new file mode 100644 index 0000000..69409f9 --- /dev/null +++ b/day-11/go.sum @@ -0,0 +1,4 @@ +github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= +github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= +golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= diff --git a/day-11/one.go b/day-11/one.go new file mode 100644 index 0000000..d0fdad5 --- /dev/null +++ b/day-11/one.go @@ -0,0 +1,87 @@ +package main + +import ( + "math" + + log "github.com/sirupsen/logrus" +) + +var runes = [][]rune{} + +type coords struct { + X int + Y int +} + +type galaxy struct { + identifier int + coords +} + +func newGalaxy(identifier, x, y int) galaxy { + return galaxy{identifier: identifier, coords: coords{X: x, Y: y}} +} + +var galaxies = make([]galaxy, 0) + +var empty = map[string][]int{ + "row": {}, + "col": {}, +} + +// shortestRoute calculates horizontal and vertical distances between points +// if empty row or columns exist then horz and vert are padded +// returns the sum of both distances +func shortestRoute(a, b coords, factor int) int { + horz := int(math.Abs(float64(b.X - a.X))) + vert := int(math.Abs(float64(b.Y - a.Y))) + + for _, row := range empty["row"] { + if b.Y > a.Y { + if row >= a.Y && row < b.Y { + log.Debug("empty row, adding to vert") + vert += (factor - 1) + } + } else { + if row >= b.Y && row < a.Y { + vert += (factor - 1) + } + } + } + for _, col := range empty["col"] { + if b.X > a.X { + if col >= a.X && col < b.X { + log.Debug("empty col, adding to horz") + horz += (factor - 1) + } + } else { + if col >= b.X && col < a.X { + log.Debug("empty col, adding to horz") + horz += (factor - 1) + } + } + } + + return int(math.Abs(float64(horz + vert))) +} + +// one returns the sum of all shortest distances between galaxies +func one(lines []string) int { + parseInput(lines) + + compared := [][]int{} + sum := 0 + for i := range galaxies { + for j := range galaxies { + if i == j || inCompared(i, j, compared) { + continue + } + + dist := shortestRoute(galaxies[i].coords, galaxies[j].coords, 2) + compared = append(compared, []int{galaxies[i].identifier, galaxies[j].identifier}) + sum += dist + } + } + + return sum +} diff --git a/day-11/solution.go b/day-11/solution.go new file mode 100644 index 0000000..926f1d4 --- /dev/null +++ b/day-11/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-11/two.go b/day-11/two.go new file mode 100644 index 0000000..70619a3 --- /dev/null +++ b/day-11/two.go @@ -0,0 +1,20 @@ +package main + +// two returns the sum of all shortest distances between galaxies if space expand by a factor of 1000000 +func two(lines []string) int { + compared := [][]int{} + sum := 0 + for i := range galaxies { + for j := range galaxies { + if i == j || inCompared(i, j, compared) { + continue + } + + dist := shortestRoute(galaxies[i].coords, galaxies[j].coords, 1000000) + compared = append(compared, []int{galaxies[i].identifier, galaxies[j].identifier}) + sum += dist + } + } + + return sum +} diff --git a/day-11/util.go b/day-11/util.go new file mode 100644 index 0000000..f165157 --- /dev/null +++ b/day-11/util.go @@ -0,0 +1,82 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "os" + "strings" +) + +// 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 +} + +func parseInput(lines []string) { + x := 0 + runes = make([][]rune, len(lines)) + for i, line := range lines { + for j, r := range line { + runes[i] = append(runes[i], r) + if r == '#' { + fmt.Println(x, j, i) + galaxies = append(galaxies, newGalaxy(x, j, i)) + x++ + } + } + } + + for i := range lines { + if strings.Count(lines[i], "#") == 0 { + empty["row"] = append(empty["row"], i) + } + } + + f := func(i int) bool { + for _, line := range lines { + if line[i] == '#' { + return false + } + } + return true + } + + for i := range lines[0] { + if f(i) { + empty["col"] = append(empty["col"], i) + } + } +} + +// inCompared returns true if both i, j coords are in compared +func inCompared(i, j int, compared [][]int) bool { + for _, comp := range compared { + if contains(comp, i) && contains(comp, j) { + return true + } + } + return false +} + +// contains returns true if a slice of elements contains a given element +func contains[T comparable](elems []T, v T) bool { + for _, s := range elems { + if v == s { + return true + } + } + return false +}