diff options
-rw-r--r-- | Program.fs | 2 | ||||
-rw-r--r-- | solutions/day14.fs | 46 |
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 |