Day 14: Restroom Redoubt
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
This one was wild. At first I started visualling it but wasn’t seeing anything. I went up to almost 80 iterations before giving up. I then went with the “no overlapping points thing” but didn’t think that was working for me either.
It was iteration 7,753. f’s sake man.
I used the a modulo operation and an if check to skip ahead to the final state. It was also tricky b/c the grid is larger than I could get my console to work with.
F#
(just the important bits)
type Velocity = Point2I [<Struct>]type Robot = {Position:Point2I; Velocity:Velocity} type Boundary = {MaxX:int; MaxY: int} let move ticks boundary robot = let newX = ((robot.Position.X + (robot.Velocity.X * ticks)) % boundary.MaxX) |> fun x -> if x < 0 then boundary.MaxX + x else x let newY = ((robot.Position.Y + (robot.Velocity.Y * ticks)) % boundary.MaxY) |> fun x -> if x < 0 then boundary.MaxY + x else x { robot with Position = {X = newX; Y = newY} } let toQuadrantScore boundary robots = let removeX = ((boundary.MaxX |> float) / 2.0) |> int let removeY = ((boundary.MaxY |> float) / 2.0) |> int ((0,0,0,0), robots) ||> Seq.fold(fun (a,b,c,d) robot -> if robot.Position.X < removeX && robot.Position.Y < removeY then (a+1,b,c,d) else if robot.Position.X > removeX && robot.Position.Y < removeY then (a,b+1,c,d) else if robot.Position.X < removeX && robot.Position.Y > removeY then (a,b,c+1,d) else if (robot.Position.X > removeX && robot.Position.Y > removeY) then (a,b,c,d+1) else (a,b,c,d) ) |> fun (a,b,c,d) -> a*b*c*d let part1impl boundary ticks robots = robots |> Seq.map(move ticks boundary) |> toQuadrantScore boundary let part1 input = (read input parse) |> part1impl {MaxX = 101; MaxY = 103 } 100 let part2 input = let robots = (read input parse) |> Array.ofSeq let boundary = {MaxX = 101; MaxY = 103 } // I'll steal the no overlapping robots approach // since I'll just be iterating through, I'll do batches of 100 numbers each in parallel and then draw it // up to 100 batches [0..100] |> List.find (fun batch -> try seq {0..100} |> Seq.pick (fun t -> // I could use PSeq here, but I'd have to remove the console stuff as the locking and fighting for the console in parallel really slows it let ticks = batch * 100 + t Console.Clear() Console.SetCursorPosition(0,0) Console.Write(ticks) let count = robots |> PSeq.map (move ticks boundary) |> PSeq.distinctBy _.Position |> PSeq.length if count = 500 then ... write to file, console
I got so lucky that “no overlapping” worked for mine. It was a very undefined problem.
Yeah I don’t know how long I would have tried to solve that on my own. I was starting to wonder if I did something wrong because I read seeing patterns every 80 iterations or so
Someone did use that periodic pattern to cut down on the search space.
I saw that. I think it sort of made sense haha. There’s a reason I’m not in statistics or analytics lol