2018 Complete!

This commit is contained in:
Brian Buller 2019-11-08 15:22:03 -06:00
parent 0044574db3
commit 056ba2d484
2 changed files with 98 additions and 128 deletions

View File

@ -0,0 +1,55 @@
package main
import "math"
type Coordinate [4]int
func (c Coordinate) Distance(b Coordinate) int {
sum := 0
for i := 0; i < 4; i++ {
sum += abs(c[i] - b[i])
}
return sum
}
type Constellation map[Coordinate]struct{}
func (c Constellation) Distance(b Coordinate) int {
shortestDistance := math.MaxInt64
for p := range c {
if p.Distance(b) < shortestDistance {
shortestDistance = p.Distance(b)
}
}
return shortestDistance
}
func (c Constellation) CelestialDistance(b Constellation) int {
shortestDistance := math.MaxInt64
for p := range c {
if b.Distance(p) < shortestDistance {
shortestDistance = b.Distance(p)
}
}
return shortestDistance
}
func (c Constellation) Add(b Coordinate) {
c[b] = struct{}{}
}
func (c Constellation) Merge(b Constellation) {
for p := range b {
c[p] = struct{}{}
delete(b, p)
}
}
func NewConstellation(b Coordinate) Constellation {
c := Constellation{b: struct{}{}}
return c
}

View File

@ -2,146 +2,70 @@ package main
import ( import (
"bufio" "bufio"
"errors"
"fmt" "fmt"
"log"
"math"
"os" "os"
"strconv"
"strings"
) )
var grid *Grid
// Pt 1
// 431 too high
func main() { func main() {
input := stdinToStringSlice() inp := StdinToStringSlice()
grid = &Grid{} fmt.Println(HotChocolatePortal(inp))
for _, v := range input { }
grid.addPoint(v)
} func HotChocolatePortal(input []string) int {
last := len(grid.constellations) var constellations []Constellation
for grid.checkMerges() {
fmt.Println("++ merge ++ ", len(grid.constellations)) for _, line := range input {
if len(grid.constellations) == last { var c Coordinate
break
if _, err := fmt.Sscanf(line, "%d,%d,%d,%d", &c[0], &c[1], &c[2], &c[3]); err != nil {
panic(err)
} }
last = len(grid.constellations)
}
fmt.Println("Points:", len(grid.points))
fmt.Println("Constellations:", len(grid.constellations))
}
type Grid struct { var found bool
points []*Pos for _, constellation := range constellations {
constellations []*Constellation if constellation.Distance(c) <= 3 {
} constellation.Add(c)
found = true
func (g *Grid) checkMerges() bool { break
for ci, c := range g.constellations {
for _, p := range c.points {
for wrki, wrk := range g.constellations {
if wrki == ci {
continue
}
if wrk.should(p) {
g.merge(ci, wrki)
g.remove(wrki)
return true
}
} }
} }
if !found {
constellations = append(constellations, NewConstellation(c))
}
} }
fmt.Println("Nothing merged")
return false
}
func (g *Grid) addPoint(inp string) { var nc []Constellation
pts := strings.Split(inp, ",") for i, a := range constellations {
pt := &Pos{ merged := false
x: atoi(pts[0]),
y: atoi(pts[1]),
z: atoi(pts[2]),
t: atoi(pts[3]),
}
g.points = append(g.points, pt)
// Check if this point is within 3 from any other points for j, b := range constellations {
cIdx := -1 if i == j {
var mergedIdx []int continue
for i, v := range g.constellations { }
if v.should(pt) {
if cIdx >= 0 { if b.CelestialDistance(a) <= 3 {
g.merge(cIdx, i) b.Merge(a)
mergedIdx = append(mergedIdx, i) merged = true
} else { break
cIdx = i
g.constellations[cIdx].add(pt)
} }
} }
}
for i := range mergedIdx {
g.remove(i)
}
if cIdx == -1 {
c := &Constellation{}
c.add(pt)
g.constellations = append(g.constellations, c)
}
}
func (g *Grid) merge(c1Idx, c2Idx int) error { if !merged {
fmt.Println(" Merging", c1Idx, c2Idx) nc = append(nc, a)
if c1Idx >= len(g.constellations) || c2Idx >= len(g.constellations) {
return errors.New("Invalid Constellation Index")
}
for _, v := range g.constellations[c2Idx].points {
g.constellations[c1Idx].add(v)
}
return nil
}
func (g *Grid) remove(remIdx int) error {
if remIdx >= len(g.constellations) {
return errors.New("Invalid Constellation Index")
}
g.constellations = append(g.constellations[:remIdx], g.constellations[remIdx+1:]...)
return nil
}
type Constellation struct {
points []*Pos
}
func (c *Constellation) should(p *Pos) bool {
for _, v := range c.points {
if v.to(p) <= 3 {
return true
} }
} }
return false
return len(nc)
} }
func (c *Constellation) add(p *Pos) { func abs(num int) int {
p.constellation = c if num < 0 {
c.points = append(c.points, p) return num * -1
}
return num
} }
type Pos struct { func StdinToStringSlice() []string {
x, y, z, t int
constellation *Constellation
}
func (p *Pos) to(p2 *Pos) int {
xs := math.Abs(float64(p.x) - float64(p2.x))
ys := math.Abs(float64(p.y) - float64(p2.y))
zs := math.Abs(float64(p.z) - float64(p2.z))
ts := math.Abs(float64(p.t) - float64(p2.t))
return int(xs + ys + zs + ts)
}
func stdinToStringSlice() []string {
var input []string var input []string
scanner := bufio.NewScanner(os.Stdin) scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() { for scanner.Scan() {
@ -149,12 +73,3 @@ func stdinToStringSlice() []string {
} }
return input return input
} }
func atoi(i string) int {
var ret int
var err error
if ret, err = strconv.Atoi(i); err != nil {
log.Fatal("Invalid Atoi: " + i)
}
return ret
}