-
-
Save Zeroto/e6ac98e700805feb0a840a7d0d5e7ec3 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
let mapWidth = day3input.IndexOf("\n") | |
let mapHeight = day3input.Length / mapWidth | |
let findSymbols input = | |
let rec iter (input:string) index x y output = | |
if index < input.Length then | |
let c = input.[index] | |
match c with | |
| c when (c < '0' || c > '9') && c <> '.' && c <> '\n' -> iter input (index + 1) (x + 1) y ((x,y,c) :: output) | |
| '\n' -> iter input (index + 1) 0 (y + 1) output | |
| _ -> iter input (index + 1) (x + 1) y output | |
else | |
output | |
iter input 0 0 0 [] | |
let findTouchingDigits (input:string) (x,y,_) = | |
let toIndex x y = (y * (mapWidth + 1)) + x | |
let adjacentCoords = [ | |
if x > 0 then (x - 1, y) | |
if x < mapWidth then (x + 1, y) | |
if y > 0 then (x, y - 1) | |
if y < mapHeight then (x, y + 1) | |
if x > 0 && y > 0 then (x - 1,y - 1) | |
if x < mapWidth && y > 0 then (x + 1, y - 1) | |
if x > 0 && y < mapHeight then (x - 1, y + 1) | |
if x < mapWidth && y < mapHeight then (x + 1,y + 1) | |
] | |
let rec expand (input:string) x y dir fn = | |
if x < 0 || x >= mapWidth then [] | |
else | |
let c = input.[toIndex x y] | |
if (c >= '0' && c <= '9') then | |
fn [(x,y,c)] (expand input (x + dir) y dir fn) | |
else | |
[] | |
let expandLeft (input:string) x y = | |
expand input x y -1 (fun a b -> b @ a) | |
let expandRight (input:string) x y = | |
expand input x y 1 (fun a b -> a @ b) | |
adjacentCoords |> List.choose (fun (x,y) -> | |
let c = input.[toIndex x y] | |
if (c >= '0' && c <= '9') then | |
let left = expandLeft input (x - 1) y | |
let right = expandRight input (x + 1) y | |
Some (left @ [(x,y,c)] @ right) | |
else | |
None | |
) | |
|> List.distinct | |
|> List.map (fun xs -> xs |> List.map (thrd) |> List.toArray |> String |> int) | |
let partNumbers = | |
(findSymbols day3input) | |
|> List.map (findTouchingDigits day3input) | |
|> List.collect id | |
printfn "Part1: %A" (partNumbers |> List.sum) | |
let gears = | |
(findSymbols day3input) | |
|> List.filter (fun (_,_,s) -> s = '*') | |
|> List.map (findTouchingDigits day3input) | |
|> List.filter (fun ds -> (ds |> List.length) = 2) | |
printfn "Part2: %A" (gears |> List.map (fun [a;b] -> a*b) |> List.sum) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment