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
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
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