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:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user