Created
December 10, 2018 06:44
-
-
Save tariknz/87b272235e7df28fc54fe2a3cb41e16f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| open System.IO | |
| open System.Text.RegularExpressions | |
| let input = File.ReadLines("2018-day-10.txt") | |
| type Star = { position: int * int; velocity: int * int } | |
| let regexPattern = "^position=<[\s]*(\-?[\d]+),[\s]*(\-?[\d]+)> velocity=<[\s]*(\-?[\d]+),[\s]*(\-?[\d]+)>$" | |
| let parser line = | |
| let groups = Regex.Match(line, regexPattern).Groups | |
| let captures = List.tail [ for g in groups -> g.Value ] | |
| { position = (int captures.[1], int captures.[0]); velocity = (int captures.[3], int captures.[2]) } | |
| let move star time = | |
| let newX = fst star.position + (fst star.velocity * time) | |
| let newY = snd star.position + (snd star.velocity * time) | |
| (newX, newY) | |
| let findMinimumBounds stars = | |
| // iterates the movements over time until it finds out the X / Y bounds are no longer shrinking | |
| let mutable time = 0 | |
| let mutable currentPositions = stars |> Seq.map (fun i -> move i time) | |
| let mutable sizeReducing = true | |
| let mutable lastMaxX, lastMaxY = 100000,100000 | |
| while sizeReducing do | |
| time <- time + 1 | |
| currentPositions <- stars |> Seq.map (fun i -> move i time) | |
| let maxX, maxY = fst (Seq.maxBy fst currentPositions), snd (Seq.maxBy snd currentPositions) | |
| if maxX > lastMaxX || maxY > lastMaxY then sizeReducing <- false | |
| lastMaxX <- maxX | |
| lastMaxY <- maxY | |
| printfn "Best Time: %d" (time - 1) | |
| stars |> Seq.map (fun i -> move i (time - 1)) | |
| let starsToCanvas positions = | |
| // find the max min bounds so we can iterate | |
| let maxX, maxY = fst (Seq.maxBy fst positions), snd (Seq.maxBy snd positions) | |
| let minX, minY = fst (Seq.minBy fst positions), snd (Seq.minBy snd positions) | |
| for x in [minX .. maxX] do | |
| for y in [minY .. maxY] do | |
| if Seq.exists (fun pos -> fst pos = x && snd pos = y) positions then printf "#" else printf "." | |
| printfn "" | |
| input | |
| |> Seq.map parser | |
| |> List.ofSeq | |
| |> findMinimumBounds | |
| |> starsToCanvas |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment