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:
114
days/06.go
Normal file
114
days/06.go
Normal 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
1013
inputs/06p.txt
Normal file
File diff suppressed because it is too large
Load Diff
11
inputs/06s1.txt
Normal file
11
inputs/06s1.txt
Normal 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
13
inputs/06s2.txt
Normal 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
|
1
main.go
1
main.go
@ -36,6 +36,7 @@ var dayMap = []day{
|
||||
&days.Day03{},
|
||||
&days.Day04{},
|
||||
&days.Day05{},
|
||||
&days.Day06{},
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
12
utilities/array.go
Normal file
12
utilities/array.go
Normal 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
|
||||
}
|
Reference in New Issue
Block a user