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 }