summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Program.fs2
-rw-r--r--solutions/day14.fs46
2 files changed, 48 insertions, 0 deletions
diff --git a/Program.fs b/Program.fs
index 7acfc6c..558d491 100644
--- a/Program.fs
+++ b/Program.fs
@@ -34,5 +34,7 @@ match (day, part) with
 | (12, 2) -> printf $"{Day12.part2 ()}\n"
 | (13, 1) -> printf $"{Day13.part1 ()}\n"
 | (13, 2) -> printf $"{Day13.part2 ()}\n"
+| (14, 1) -> printf $"{Day14.part1 ()}\n"
+| (14, 2) -> printf $"{Day14.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/day14.fs b/solutions/day14.fs
new file mode 100644
index 0000000..0bc0464
--- /dev/null
+++ b/solutions/day14.fs
@@ -0,0 +1,46 @@
+module Solutions.Day14
+
+open System
+open System.IO
+
+let lineToCoords (line: string) =
+    line.Split([|","; " -> "|], StringSplitOptions.None) 
+    |> Array.map int
+    |> Array.chunkBySize 2
+    |> Array.map (fun x -> x[0], x[1])
+
+let coordsToPointSet (coords: (int * int) array) =
+    let coordLine (x1, y1) (x2, y2) =
+        seq { for x in min x1 x2 .. max x1 x2 do for y in min y1 y2 .. max y1 y2 -> (x, y) }
+        |> Set.ofSeq
+    Array.fold2 (fun points coord1 coord2 -> coordLine coord1 coord2 |> Set.union points) Set.empty coords[..Array.length coords - 2] coords[1..]
+
+let cave = File.ReadAllLines("inputs/day14.txt") |> Array.map (lineToCoords >> coordsToPointSet) |> Set.unionMany
+
+let startPoint = (500, 0)
+
+let rec watch abyss (cave, p1) =
+    let rec drop cave p1 (x, y) =
+        [ x, y+1; x-1, y+1; x+1, y+1]
+        |> Seq.tryFind (fun n -> not (Set.contains n cave))
+        |> (function
+            | None -> Set.add (x, y) cave, p1
+            | Some (nx, ny) when ny = abyss ->
+                Set.add (nx, ny) cave,
+                (if p1 = -1 then Set.count cave else p1)
+            | Some n -> drop cave p1 n)
+    
+    if Set.contains startPoint cave then 
+        (p1, Set.count cave)
+    else
+        watch abyss (drop cave p1 startPoint)
+
+let solution =
+    let abyss = (cave |> Seq.maxBy snd |> snd) + 1
+    let r = Set.count cave
+    let rns = watch abyss (cave, -1)
+    (fst rns - r), (snd rns - r)
+
+let part1 () = fst solution
+
+let part2 () = snd solution
\ No newline at end of file