summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorBrian Chu <brianmchu42@gmail.com>2022-12-09 21:30:18 -0800
committerBrian Chu <brianmchu42@gmail.com>2022-12-09 21:30:18 -0800
commitcdabc548b41b1990393b6d563c813352bb8dbf01 (patch)
tree2110481babcd4dc0fe54d75789582d3017a33222
parentc6b298b561c66f1b3255baee071ad6c058ea4e66 (diff)
downloadAdventOfCode2022-cdabc548b41b1990393b6d563c813352bb8dbf01.tar.gz
solution for day 8
-rw-r--r--Program.fs2
-rw-r--r--solutions/day8.fs53
2 files changed, 55 insertions, 0 deletions
diff --git a/Program.fs b/Program.fs
index 7d12388..ff91000 100644
--- a/Program.fs
+++ b/Program.fs
@@ -22,5 +22,7 @@ match (day, part) with
 | (6, 2) -> printf $"{Day6.part2 ()}\n"
 | (7, 1) -> printf $"{Day7.part1 ()}\n"
 | (7, 2) -> printf $"{Day7.part2 ()}\n"
+| (8, 1) -> printf $"{Day8.part1 ()}\n"
+| (8, 2) -> printf $"{Day8.part2 ()}\n"
 | (x, y) when (1 <= x && x <= 25) && (y = 1 || y = 2)  -> raise (NotImplemented("not implemented yet"))
 | _ -> raise (NotImplemented("invalid values"))
\ No newline at end of file
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