Day 6 solution

I'm reasonably happy with this. I started with a bi-directional linked list, but realized that a flat list of all nodes came in handy for one use case while the linked list came in handy for another, so I settled on that.
This commit is contained in:
2022-06-09 13:24:12 -05:00
parent 870abdf579
commit d7db069031
6 changed files with 1164 additions and 0 deletions

114
days/06.go Normal file
View File

@ -0,0 +1,114 @@
package days
import (
"fmt"
"strings"
"parnic.com/aoc2019/utilities"
)
type body struct {
orbits *body
obj string
}
type Day06 struct {
allBodies []*body
}
func (d *Day06) Parse() {
d.allBodies = make([]*body, 0)
getOrAddBody := func(obj string) *body {
target := d.findBody(obj)
if target == nil {
target = &body{
obj: obj,
}
d.allBodies = append(d.allBodies, target)
}
return target
}
lines := utilities.GetStringLines("06p")
for _, line := range lines {
bodies := strings.Split(line, ")")
newBody := getOrAddBody(bodies[1])
target := getOrAddBody(bodies[0])
newBody.orbits = target
}
}
func (d *Day06) findBody(obj string) *body {
for _, checkBody := range d.allBodies {
if checkBody.obj == obj {
return checkBody
}
}
return nil
}
func (d Day06) Num() int {
return 6
}
func (d *Day06) Part1() string {
orbits := 0
for _, obj := range d.allBodies {
next := obj.orbits
for next != nil {
next = next.orbits
orbits++
}
}
return fmt.Sprintf("Total orbits: %s%d%s", utilities.TextBold, orbits, utilities.TextReset)
}
func (d *Day06) Part2() string {
you := d.findBody("YOU")
san := d.findBody("SAN")
youChildren := make([]*body, 0)
next := you.orbits
for next != nil {
youChildren = append(youChildren, next)
next = next.orbits
}
var linkingNode *body
next = san.orbits
for next != nil {
if utilities.ArrayContains(youChildren, next) {
linkingNode = next
break
}
next = next.orbits
}
if linkingNode == nil {
panic("")
}
getDistToLinking := func(start *body) int {
dist := 0
next = start.orbits
for next != nil {
if next == linkingNode {
break
}
dist++
next = next.orbits
}
return dist
}
distYouToLinking := getDistToLinking(you)
distSanToLinking := getDistToLinking(san)
return fmt.Sprintf("Transfers to get to Santa: %s%d%s", utilities.TextBold, distYouToLinking+distSanToLinking, utilities.TextReset)
}

1013
inputs/06p.txt Normal file

File diff suppressed because it is too large Load Diff

11
inputs/06s1.txt Normal file
View File

@ -0,0 +1,11 @@
COM)B
B)C
C)D
D)E
E)F
B)G
G)H
D)I
E)J
J)K
K)L

13
inputs/06s2.txt Normal file
View File

@ -0,0 +1,13 @@
COM)B
B)C
C)D
D)E
E)F
B)G
G)H
D)I
E)J
J)K
K)L
K)YOU
I)SAN

View File

@ -36,6 +36,7 @@ var dayMap = []day{
&days.Day03{},
&days.Day04{},
&days.Day05{},
&days.Day06{},
}
func main() {

12
utilities/array.go Normal file
View File

@ -0,0 +1,12 @@
package utilities
// ArrayContains returns whether the specified array contains the specified value
func ArrayContains[T comparable](array []T, val T) bool {
for _, v := range array {
if v == val {
return true
}
}
return false
}