diff options
Diffstat (limited to 'solutions')
-rw-r--r-- | solutions/day8.fs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/solutions/day8.fs b/solutions/day8.fs new file mode 100644 index 0000000..757cb74 --- /dev/null +++ b/solutions/day8.fs @@ -0,0 +1,53 @@ +namespace Solutions + +module Day8 = + open System.IO + + let input = File.ReadLines("inputs/day8.txt") |> Array.ofSeq |> Array.map (Array.ofSeq >> Array.map (fun x -> int x - int '0')) |> array2D + + let rec countVisible line index indices max = + if line = [||] then indices + else + let current = Array.head line + if current > max then + countVisible (Array.tail line) (index + 1) (Set.add index indices) current + else + countVisible (Array.tail line) (index + 1) indices max + + let countBidirectional goHorizontal index line = + let dirSet dir = + countVisible (Array.tail dir) 1 (Set.singleton 0) (Array.head dir) + let forwards = dirSet line + let backwards = dirSet (Array.rev line) |> Set.map (fun x -> Array.length line - 1 - x) + Set.union forwards backwards |> Set.map(fun x -> if goHorizontal then (index, x) else (x, index)) + + let countGridVisible grid = + let rows, cols = Array2D.length1 grid, Array2D.length2 grid + let rowSet = seq { for x in 0..rows - 1 -> x } |> Seq.map (fun x -> grid[x, *] |> countBidirectional true x) |> Set.unionMany + let colSet = seq { for y in 0..cols - 1 -> y } |> Seq.map (fun y -> grid[*, y] |> countBidirectional false y) |> Set.unionMany + Set.union rowSet colSet |> Set.count + + let part1 () = countGridVisible input + + let getViewingDistance index (line: int array) = + let before, after = Array.rev line[..index - 1], line[index + 1..] + let getDistance height trees = + try + 1 + Array.findIndex (fun x -> x >= height) trees + with + | :? System.Collections.Generic.KeyNotFoundException -> Array.length trees + | :? System.ArgumentNullException -> failwith "should never happen" + + getDistance line[index] before * getDistance line[index] after + + let getScore (grid: int[,]) (x, y) = + let row, col = grid[x, *], grid[*, y] + let hScore = getViewingDistance y row + let vScore = getViewingDistance x col + hScore * vScore + + let part2 () = + seq {for x in 0..Array2D.length1 input - 1 do + for y in 0..Array2D.length2 input - 1 -> (x, y)} + |> Seq.map (getScore input) + |> Seq.max \ No newline at end of file |