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 (
"bufio"
"errors"
"fmt"
"log"
"math"
"os"
"strconv"
"strings"
)
var grid *Grid
// Pt 1
// 431 too high
func main() {
input := stdinToStringSlice()
grid = &Grid{}
for _, v := range input {
grid.addPoint(v)
}
last := len(grid.constellations)
for grid.checkMerges() {
fmt.Println("++ merge ++ ", len(grid.constellations))
if len(grid.constellations) == last {
break
inp := StdinToStringSlice()
fmt.Println(HotChocolatePortal(inp))
}
func HotChocolatePortal(input []string) int {
var constellations []Constellation
for _, line := range input {
var c Coordinate
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 {
points []*Pos
constellations []*Constellation
}
func (g *Grid) checkMerges() bool {
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
}
var found bool
for _, constellation := range constellations {
if constellation.Distance(c) <= 3 {
constellation.Add(c)
found = true
break
}
}
if !found {
constellations = append(constellations, NewConstellation(c))
}
}
fmt.Println("Nothing merged")
return false
}
func (g *Grid) addPoint(inp string) {
pts := strings.Split(inp, ",")
pt := &Pos{
x: atoi(pts[0]),
y: atoi(pts[1]),
z: atoi(pts[2]),
t: atoi(pts[3]),
}
g.points = append(g.points, pt)
var nc []Constellation
for i, a := range constellations {
merged := false
// Check if this point is within 3 from any other points
cIdx := -1
var mergedIdx []int
for i, v := range g.constellations {
if v.should(pt) {
if cIdx >= 0 {
g.merge(cIdx, i)
mergedIdx = append(mergedIdx, i)
} else {
cIdx = i
g.constellations[cIdx].add(pt)
for j, b := range constellations {
if i == j {
continue
}
if b.CelestialDistance(a) <= 3 {
b.Merge(a)
merged = true
break
}
}
}
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 {
fmt.Println(" Merging", c1Idx, c2Idx)
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
if !merged {
nc = append(nc, a)
}
}
return false
return len(nc)
}
func (c *Constellation) add(p *Pos) {
p.constellation = c
c.points = append(c.points, p)
func abs(num int) int {
if num < 0 {
return num * -1
}
return num
}
type Pos struct {
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 {
func StdinToStringSlice() []string {
var input []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
@ -149,12 +73,3 @@ func stdinToStringSlice() []string {
}
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
}