2024 Day 14 Complete!
This commit is contained in:
164
2024/day14/main.go
Normal file
164
2024/day14/main.go
Normal file
@@ -0,0 +1,164 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
part1(inp)
|
||||
fmt.Println()
|
||||
part2(inp)
|
||||
}
|
||||
|
||||
func part1(inp []string) {
|
||||
fmt.Println("# Part 1")
|
||||
// Main Input size
|
||||
sizeX, sizeY := 101, 103
|
||||
bots := parseInput(inp, sizeX, sizeY)
|
||||
for i := 0; i < 100; i++ {
|
||||
for j := range bots {
|
||||
bots[j].Move()
|
||||
}
|
||||
}
|
||||
for i := range bots {
|
||||
fmt.Println(bots[i])
|
||||
}
|
||||
qCnt := make([]int, 4)
|
||||
for y := 0; y < sizeY; y++ {
|
||||
for x := 0; x < sizeX; x++ {
|
||||
if x == sizeX/2 || y == sizeY/2 {
|
||||
fmt.Print(" ")
|
||||
continue
|
||||
}
|
||||
bCnt := 0
|
||||
for i := range bots {
|
||||
if x == bots[i].X && y == bots[i].Y {
|
||||
bCnt++
|
||||
if x < sizeX/2 {
|
||||
if y < sizeY/2 {
|
||||
qCnt[0]++
|
||||
} else {
|
||||
qCnt[2]++
|
||||
}
|
||||
} else {
|
||||
if y < sizeY/2 {
|
||||
qCnt[1]++
|
||||
} else {
|
||||
qCnt[3]++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if bCnt > 0 {
|
||||
fmt.Print(bCnt)
|
||||
} else {
|
||||
fmt.Print(".")
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Println("Safety Factor:", (qCnt[0] * qCnt[1] * qCnt[2] * qCnt[3]))
|
||||
}
|
||||
|
||||
func part2(inp []string) {
|
||||
fmt.Println("# Part 2")
|
||||
// Main Input size
|
||||
sizeX, sizeY := 101, 103
|
||||
bots := parseInput(inp, sizeX, sizeY)
|
||||
printState := func() {
|
||||
for y := 0; y < sizeY; y++ {
|
||||
for x := 0; x < sizeX; x++ {
|
||||
btCnt := 0
|
||||
for _, b := range bots {
|
||||
if b.X == x && b.Y == y {
|
||||
btCnt++
|
||||
}
|
||||
}
|
||||
if btCnt == 0 {
|
||||
fmt.Print(".")
|
||||
} else if btCnt < 10 {
|
||||
fmt.Print(btCnt)
|
||||
} else {
|
||||
fmt.Print("#")
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
// My hypothesis: most bots will be close to each other for the answer
|
||||
lowest := h.MAX_INT
|
||||
var lowStdX, lowStdY float64
|
||||
for steps := 0; steps < 10000000; steps++ {
|
||||
xs := make([]int, 0, len(bots))
|
||||
ys := make([]int, 0, len(bots))
|
||||
for j := range bots {
|
||||
bots[j].Move()
|
||||
xs = append(xs, bots[j].X)
|
||||
ys = append(ys, bots[j].Y)
|
||||
}
|
||||
// After finding it, I added this to print it out :D
|
||||
if steps == 7036 {
|
||||
printState()
|
||||
}
|
||||
wrkX, wrkY := stdev(xs), stdev(ys)
|
||||
if lowest == h.MAX_INT || (wrkX < lowStdX && wrkY < lowStdY) {
|
||||
fmt.Println(lowest, ":", lowStdX, lowStdY)
|
||||
lowStdX, lowStdY, lowest = wrkX, wrkY, steps
|
||||
}
|
||||
}
|
||||
fmt.Println("Steps to Easter Egg:", lowest)
|
||||
}
|
||||
|
||||
func stdev(vals []int) float64 {
|
||||
m := 0.0
|
||||
for _, w := range vals {
|
||||
m += float64(w)
|
||||
}
|
||||
m /= float64(len(vals))
|
||||
v := 0.0
|
||||
for _, w := range vals {
|
||||
diff := float64(w) - m
|
||||
v += diff * diff
|
||||
}
|
||||
return math.Sqrt(v / float64(len(vals)))
|
||||
}
|
||||
|
||||
var botRaw = "p=%d,%d v=%d,%d"
|
||||
|
||||
type Bot struct {
|
||||
X, Y, Vx, Vy int
|
||||
mX, mY int
|
||||
}
|
||||
|
||||
func NewBot(inp string) *Bot {
|
||||
b := Bot{}
|
||||
fmt.Sscanf(inp, botRaw, &b.X, &b.Y, &b.Vx, &b.Vy)
|
||||
return &b
|
||||
}
|
||||
|
||||
func (b *Bot) Move() {
|
||||
b.X = (b.X + b.Vx + b.mX) % b.mX
|
||||
b.Y = (b.Y + b.Vy + b.mY) % b.mY
|
||||
}
|
||||
|
||||
func (b *Bot) Overlaps(bt *Bot) bool {
|
||||
return b.X == bt.X && b.Y == bt.Y
|
||||
}
|
||||
|
||||
func (b Bot) String() string {
|
||||
return fmt.Sprintf(botRaw, b.X, b.Y, b.Vx, b.Vy)
|
||||
}
|
||||
|
||||
func parseInput(inp []string, mX, mY int) []*Bot {
|
||||
var ret []*Bot
|
||||
for i := range inp {
|
||||
b := NewBot(inp[i])
|
||||
b.mX, b.mY = mX, mY
|
||||
ret = append(ret, b)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
Reference in New Issue
Block a user