summary refs log blame commit diff stats
path: root/solutions/day8.fs
blob: 8978700b3d407face8a6dd0882ea546f398e45ac (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11

                     
 
                                                                                                                                          
 





                                                                                      
            






































                                                                                                                                   
module Solutions.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