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.Day03{},
|
||||||
&days.Day04{},
|
&days.Day04{},
|
||||||
&days.Day05{},
|
&days.Day05{},
|
||||||
|
&days.Day06{},
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
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