Skip to content

Instantly share code, notes, and snippets.

@mastoj
Created December 5, 2021 20:52
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 mastoj/0e685ecee7eb0c19a48569e1275784ab to your computer and use it in GitHub Desktop.
Save mastoj/0e685ecee7eb0c19a48569e1275784ab to your computer and use it in GitHub Desktop.
Day 05
open System.IO
let path = "05-input.data"
let sample = """0,9 -> 5,9
8,0 -> 0,8
9,4 -> 3,4
2,2 -> 2,1
7,0 -> 7,4
6,4 -> 2,0
0,9 -> 2,9
3,4 -> 1,4
0,0 -> 8,8
5,5 -> 8,2"""
let lines =
File.ReadAllLines(path)
|> List.ofArray
let sampleLines = sample.Split("\n") |> List.ofArray
let useSample = false
let input = if useSample then sampleLines else lines
type Point = int*int
let pointStrToPoint (pointStr: string) =
let [|x; y|] = pointStr.Split(",") |> Array.map int
(x,y)
let inputLineToCoordinates (inputLine: string) =
let [startPointStr; _ ; endPointStr] =
inputLine.Split(" ") |> List.ofArray
let startPoint = startPointStr |> pointStrToPoint
let endPoint = endPointStr |> pointStrToPoint
startPoint, endPoint
let (|Vertical|Horizontal|Diagonal|) ((x1, y1), (x2, y2) as line) =
if x1 = x2 then Vertical line
else if y1 = y2 then Horizontal line
else Diagonal line
let isDiagonal line =
match line with
| Diagonal _ -> true
| _ -> false
let isNotDiagonal line = line |> isDiagonal |> not
let drawLine line =
match line with
| Vertical ((x1, y1), (x2, y2)) | Horizontal ((x1, y1), (x2, y2)) ->
[ for x in (min x1 x2) .. (max x1 x2) do
for y in (min y1 y2) .. (max y1 y2) do
yield (x,y) ]
| Diagonal ((x1, y1), (x2, y2)) ->
let getPos (i1, i2) =
let values = [(min i1 i2) .. (max i1 i2)]
if i1 > i2 then values |> List.rev else values
let yPos = getPos (y1, y2)
let xPos = getPos (x1, x2)
xPos
|> List.mapi (fun index x -> x,yPos.[index])
let result1 =
input
|> List.map inputLineToCoordinates
|> List.filter (isNotDiagonal)
|> List.map drawLine
|> List.concat
|> List.groupBy id
|> List.filter (fun (_, value) -> value.Length > 1)
|> (fun r -> r.Length)
let result2 =
input
|> List.map inputLineToCoordinates
|> List.map drawLine
|> List.concat
|> List.groupBy id
|> List.sortBy (fun (_, value) -> value.Length)
|> List.filter (fun (_, value) -> value.Length > 1)
|> (fun r -> r.Length)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment