This commit is contained in:
onyx-and-iris 2023-12-11 18:41:46 +00:00
parent 7cf383d9c9
commit cc6a0942fb
6 changed files with 222 additions and 0 deletions

8
day-11/go.mod Normal file
View File

@ -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
)

4
day-11/go.sum Normal file
View File

@ -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=

87
day-11/one.go Normal file
View File

@ -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
}

21
day-11/solution.go Normal file
View File

@ -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)
}

20
day-11/two.go Normal file
View File

@ -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
}

82
day-11/util.go Normal file
View File

@ -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
}