Brian Buller
1ec6280623
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.
93 lines
2.0 KiB
Go
93 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
func main() {
|
|
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 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
|
|
}
|
|
}
|
|
}
|
|
for c, rs := range bots {
|
|
if largestPos.Distance(c) <= largestRadius {
|
|
count += len(rs)
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
func ClosestSuccess(bots Bots) int {
|
|
var cur, topLeft, bottomRight Coordinate
|
|
zoom := 1 << (strconv.IntSize - 2)
|
|
|
|
for {
|
|
zoomedBots := make(Bots)
|
|
best := struct {
|
|
pos Coordinate
|
|
count int
|
|
}{}
|
|
|
|
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 StdinToStringSlice() []string {
|
|
var input []string
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
for scanner.Scan() {
|
|
input = append(input, scanner.Text())
|
|
}
|
|
return input
|
|
}
|