Skip to content

Instantly share code, notes, and snippets.

@sitharus
Created December 4, 2019 19:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sitharus/33ccdc9097484e5af52a01f15803f346 to your computer and use it in GitHub Desktop.
Save sitharus/33ccdc9097484e5af52a01f15803f346 to your computer and use it in GitHub Desktop.
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