2018 Day 23*

Had to find someone else's python solution to get an answer.
Need to pull it apart and figure out what's wrong with my solution.
This commit is contained in:
2019-11-07 15:43:14 -06:00
parent 7c9742fb73
commit 1ec6280623
6 changed files with 1198 additions and 82 deletions

View File

@@ -3,88 +3,86 @@ package main
import (
"bufio"
"fmt"
"log"
"math"
"os"
"strconv"
"strings"
)
var collective *Collective
func main() {
input := stdinToStringSlice()
collective = &Collective{}
for _, v := range input {
collective.bots = append(collective.bots, NewBot(v))
}
part1()
inp := StdinToStringSlice()
fmt.Printf("# Part 1\nIn Range of Strongest: %d\n", StrongestReachable(NewBots(inp)))
// Part 2: 94270682 is too low
// 94481123 is too low
fmt.Printf("# Part 2\nClosest Success: %d\n", ClosestSuccess(NewBots(inp)))
}
func part1() {
s := collective.strongest()
fmt.Println("= Part 1 =")
fmt.Println(len(collective.inRange(s)))
}
func part2() {
finder := &Bot{}
}
type Collective struct {
bots []*Bot
}
func (c *Collective) inRange(b *Bot) []*Bot {
var ret []*Bot
for _, v := range c.bots {
if c.distance(b, v) <= b.radius {
ret = append(ret, v)
func StrongestReachable(bots Bots) int {
var largestRadius, count int
var largestPos Coordinate
for c, rs := range bots {
for _, r := range rs {
if r > largestRadius {
largestPos = c
largestRadius = r
}
}
}
return ret
}
func (c *Collective) strongest() *Bot {
strongest := c.bots[0]
for _, v := range c.bots {
if v.radius > strongest.radius {
strongest = v
for c, rs := range bots {
if largestPos.Distance(c) <= largestRadius {
count += len(rs)
}
}
return strongest
return count
}
func (c *Collective) distance(b1, b2 *Bot) int {
xs := math.Abs(float64(b1.x) - float64(b2.x))
ys := math.Abs(float64(b1.y) - float64(b2.y))
zs := math.Abs(float64(b1.z) - float64(b2.z))
return int(xs + ys + zs)
}
func ClosestSuccess(bots Bots) int {
var cur, topLeft, bottomRight Coordinate
zoom := 1 << (strconv.IntSize - 2)
type Bot struct {
x, y, z int
radius int
}
for {
zoomedBots := make(Bots)
best := struct {
pos Coordinate
count int
}{}
func NewBot(args string) *Bot {
pts := strings.Split(args, ", ")
pos := strings.Split(pts[0][5:len(pts[0])-1], ",")
r := strings.Split(pts[1], "=")[1]
return &Bot{
x: atoi(pos[0]),
y: atoi(pos[1]),
z: atoi(pos[2]),
radius: atoi(r),
for c, rs := range bots {
for _, r := range rs {
zc := Coordinate{c.X / zoom, c.Y / zoom, c.Z / zoom}
zoomedBots[zc] = append(zoomedBots[zc], r/zoom)
}
}
for cur.X = topLeft.X; cur.X <= bottomRight.X; cur.X++ {
for cur.Y = topLeft.Y; cur.Y <= bottomRight.Y; cur.Y++ {
for cur.Z = topLeft.Z; cur.Z <= bottomRight.Z; cur.Z++ {
c := zoomedBots.HaveInRange(cur)
// skip less bots
if c < best.count {
continue
}
// skip same amount of bots but Distance from Zero is the same or more
if c == best.count && Zero.Distance(cur) >= Zero.Distance(best.pos) {
continue
}
// more bots or same and closer to Zero
best.pos, best.count = cur, c
}
}
}
// zoom in
topLeft.X, topLeft.Y, topLeft.Z = (best.pos.X-1)<<1, (best.pos.Y-1)<<1, (best.pos.Z-1)<<1
bottomRight.X, bottomRight.Y, bottomRight.Z = (best.pos.X+1)<<1, (best.pos.Y+1)<<1, (best.pos.Z+1)<<1
zoom >>= 1
if zoom == 0 {
return Zero.Distance(best.pos)
}
}
}
func (b *Bot) string() string {
return fmt.Sprintf("(%d,%d,%d : %d)", b.x, b.y, b.z, b.radius)
}
func stdinToStringSlice() []string {
func StdinToStringSlice() []string {
var input []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
@@ -92,12 +90,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")
}
return ret
}