2019 Day 6 Complete!
This commit is contained in:
162
2019/day06/main.go
Normal file
162
2019/day06/main.go
Normal file
@@ -0,0 +1,162 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := helpers.StdinToStringSlice()
|
||||
allObjects = make(map[string]*Object)
|
||||
for _, v := range inp {
|
||||
pts := strings.Split(v, ")")
|
||||
var obj1, obj2 *Object
|
||||
var ok bool
|
||||
if obj1, ok = allObjects[pts[0]]; !ok {
|
||||
obj1 = NewObject(pts[0])
|
||||
allObjects[pts[0]] = obj1
|
||||
}
|
||||
if obj2, ok = allObjects[pts[1]]; !ok {
|
||||
obj2 = NewObject(pts[1])
|
||||
allObjects[pts[1]] = obj2
|
||||
obj1.addMoon(pts[1])
|
||||
}
|
||||
obj2.setOrbiting(pts[0])
|
||||
}
|
||||
fmt.Println(len(allObjects), "total objects")
|
||||
part1()
|
||||
part2()
|
||||
}
|
||||
|
||||
func part1() {
|
||||
var ret int
|
||||
for _, v := range allObjects {
|
||||
ret += v.countOrbits()
|
||||
}
|
||||
fmt.Println("Part 1:", ret)
|
||||
}
|
||||
|
||||
func part2() {
|
||||
if _, ok := allObjects["YOU"]; !ok {
|
||||
panic("Invalid input for part 2")
|
||||
}
|
||||
if _, ok := allObjects["SAN"]; !ok {
|
||||
panic("Invalid input for part 2")
|
||||
}
|
||||
you := allObjects["YOU"]
|
||||
youOrbits := you.getOrbitsList()
|
||||
san := allObjects["SAN"]
|
||||
sanOrbits := san.getOrbitsList()
|
||||
min := -1
|
||||
var minShared *Object
|
||||
for _, yv := range youOrbits {
|
||||
for _, sv := range sanOrbits {
|
||||
if yv == sv {
|
||||
ySteps := you.stepsTo(yv.Name)
|
||||
sSteps := san.stepsTo(sv.Name)
|
||||
if min == -1 || ySteps+sSteps < min {
|
||||
min = ySteps + sSteps
|
||||
minShared = yv
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if minShared == nil {
|
||||
panic("No shared object found!")
|
||||
}
|
||||
fmt.Println("Closest Ancestor: ", minShared.Name)
|
||||
fmt.Println("Steps: ", min)
|
||||
}
|
||||
|
||||
var allObjects map[string]*Object
|
||||
|
||||
type Object struct {
|
||||
Name string
|
||||
Moons []*Object
|
||||
Orbits *Object
|
||||
}
|
||||
|
||||
func NewObject(nm string) *Object {
|
||||
return &Object{Name: nm}
|
||||
}
|
||||
|
||||
func (o *Object) getOrbitsList() []*Object {
|
||||
var ret []*Object
|
||||
if o.Orbits == nil {
|
||||
return ret
|
||||
}
|
||||
ret = append(ret, o.Orbits)
|
||||
return append(ret, o.Orbits.getOrbitsList()...)
|
||||
}
|
||||
|
||||
func (o *Object) stepsTo(nm string) int {
|
||||
// First check if this is it
|
||||
if o.Name == nm {
|
||||
// If so, remove the last transfer
|
||||
return -1
|
||||
}
|
||||
// Now check if it's a descendant of this
|
||||
if ret := o.hasDesc(nm); ret != nil {
|
||||
return ret.stepsTo(nm) + 1
|
||||
}
|
||||
// Ok, we must have to go up another level
|
||||
if o.Orbits == nil {
|
||||
fmt.Println(o.Name)
|
||||
panic("Nothing else to check!")
|
||||
}
|
||||
return o.Orbits.stepsTo(nm) + 1
|
||||
}
|
||||
|
||||
func (o *Object) OrbitsAround(nm string) bool {
|
||||
if o.Orbits == nil {
|
||||
return false
|
||||
}
|
||||
if o.Orbits.Name == nm {
|
||||
return true
|
||||
}
|
||||
return o.Orbits.OrbitsAround(nm)
|
||||
}
|
||||
|
||||
// hasDesc checks all moons to see if one is or has the requested moon
|
||||
// and returns the object that does
|
||||
func (o *Object) hasDesc(nm string) *Object {
|
||||
for _, v := range o.Moons {
|
||||
if v.Name == nm {
|
||||
return v
|
||||
}
|
||||
if d := v.hasDesc(nm); d != nil {
|
||||
return d
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Object) countOrbits() int {
|
||||
if o.Name == "COM" {
|
||||
return 0
|
||||
}
|
||||
return o.Orbits.countOrbits() + 1
|
||||
}
|
||||
|
||||
func (o *Object) setOrbiting(nm string) {
|
||||
if v, ok := allObjects[nm]; !ok {
|
||||
panic(fmt.Sprintf("Object not found (%s)", nm))
|
||||
} else {
|
||||
o.Orbits = v
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Object) addMoon(nm string) {
|
||||
if v, ok := allObjects[nm]; !ok {
|
||||
panic(fmt.Sprintf("Object not found (%s)", nm))
|
||||
} else {
|
||||
for k := range o.Moons {
|
||||
if o.Moons[k].Name == nm {
|
||||
return
|
||||
}
|
||||
}
|
||||
o.Moons = append(o.Moons, v)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user