mirror of
https://github.com/onyx-and-iris/aoc2023.git
synced 2024-11-21 18:00:47 +00:00
day-11
This commit is contained in:
parent
7cf383d9c9
commit
cc6a0942fb
8
day-11/go.mod
Normal file
8
day-11/go.mod
Normal 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
4
day-11/go.sum
Normal 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
87
day-11/one.go
Normal 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
21
day-11/solution.go
Normal 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
20
day-11/two.go
Normal 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
82
day-11/util.go
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user