Created
December 4, 2019 19:37
-
-
Save sitharus/33ccdc9097484e5af52a01f15803f346 to your computer and use it in GitHub Desktop.
This file contains 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 | |
type direction = Up of int | Down of int | Left of int | Right of int | |
let parseMove (move:string) = | |
let value = int <| move.Substring(1) | |
match move.Substring(0, 1) with | |
| "U" -> Up value | |
| "D" -> Down value | |
| "L" -> Left value | |
| "R" -> Right value | |
| _ -> failwith "Unknown move" | |
let calcmove distance makeMove = List.rev << List.ofSeq <| seq { for i in 1..distance do yield makeMove i } | |
let positions move (x, y, d) = | |
match parseMove move with | |
| Up i -> calcmove i <| fun n -> (x, y + n, d + n) | |
| Down i -> calcmove i <| fun n -> (x, y - n, d + n) | |
| Left i -> calcmove i <| fun n -> (x - n, y, d + n) | |
| Right i -> calcmove i <| fun n -> (x + n, y, d + n) | |
let rec wirePoints moves current = | |
match moves with | |
| head::tail -> | |
let move = positions head current | |
move :: (wirePoints tail <| List.head move) | |
| [] -> List.empty | |
let positionOnly = List.map (fun (x, y, _) -> (x, y)) | |
let makeDict = Map.ofSeq << Seq.sortBy (fun (_, d) -> d) << Seq.map (fun (x, y, d) -> ((x, y), d)) | |
let getWire (wireString:string) = | |
let wire = List.ofArray <| wireString.Split(",") | |
let wirePositions = List.concat <| wirePoints wire (0,0,0) | |
Set.ofList <| positionOnly wirePositions, makeDict wirePositions | |
[<EntryPoint>] | |
let main argv = | |
let wire1Positions, wire1Lengths = getWire argv.[0] | |
let wire2Positions, wire2Lengths = getWire argv.[1] | |
let intersections = Set.intersect wire1Positions wire2Positions | |
let withWireLengths = Seq.map (fun pos -> (pos, Map.find pos wire1Lengths + Map.find pos wire2Lengths)) intersections | |
let minWireLength = Seq.head << Seq.sortBy (fun (_, d) -> d) <| withWireLengths | |
printfn "%A" minWireLength | |
let distances = Seq.map (fun (x, y) -> (abs x + abs y, x, y)) << Seq.filter (fun (x, y) -> x <> 0 && y <> 0) <| intersections | |
let (distance, x, y) = Seq.head << Seq.sortBy (fun (distance, _, _) -> distance) <| distances | |
printfn "%d (%d %d)" distance x y | |
0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment