summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--AoC2022.fsproj4
-rw-r--r--Program.fs2
-rw-r--r--solutions/day9.fs39
3 files changed, 45 insertions, 0 deletions
diff --git a/AoC2022.fsproj b/AoC2022.fsproj
index acbbdb1..13269ee 100644
--- a/AoC2022.fsproj
+++ b/AoC2022.fsproj
@@ -7,4 +7,8 @@
     <Compile Include="solutions/**" />
     <Compile Include="Program.fs" />
   </ItemGroup>
+  <ItemGroup>
+    <PackageReference Include="FSharpPlus" Version="1.3.2" />
+    <PackageReference Update="FSharp.Core" Version="6.0.6" />
+  </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/Program.fs b/Program.fs
index ff91000..4d78505 100644
--- a/Program.fs
+++ b/Program.fs
@@ -24,5 +24,7 @@ match (day, part) with
 | (7, 2) -> printf $"{Day7.part2 ()}\n"
 | (8, 1) -> printf $"{Day8.part1 ()}\n"
 | (8, 2) -> printf $"{Day8.part2 ()}\n"
+| (9, 1) -> printf $"{Day9.part1 ()}\n"
+| (9, 2) -> printf $"{Day9.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/day9.fs b/solutions/day9.fs
new file mode 100644
index 0000000..9c1407f
--- /dev/null
+++ b/solutions/day9.fs
@@ -0,0 +1,39 @@
+namespace Solutions
+
+module Day9 =
+    open System.IO
+    open System.Text.RegularExpressions
+    open FSharpPlus.Operators
+
+    let parseInstruction line =
+        let groups = Regex.Match(line, "([LRUD]) (\d+)").Groups
+                     |> Seq.map (fun x -> x.Value)
+                     |> Array.ofSeq
+        match groups[1], groups[2] with
+        | "L", count -> List.replicate (int count) (-1, 0)
+        | "R", count -> List.replicate (int count) (1, 0)
+        | "U", count -> List.replicate (int count) (0, 1)
+        | "D", count -> List.replicate (int count) (0, -1)
+        | _ -> failwith "invalid input"
+
+    let headPositions steps = List.scan (fun (x1, y1) (x2, y2) -> (x1 + x2, y1 + y2)) (0, 0) steps
+    let instructions = File.ReadLines("inputs/day9.txt") |> Seq.map parseInstruction |> Seq.concat |> List.ofSeq |> headPositions    
+
+    let rec followPath (rope: list<int * int>) (tailSet: Set<int*int>) (heads: list<int*int>) =
+        let touches pointA pointB = abs (fst pointA - fst pointB) <= 1 && abs (snd pointA - snd pointB) <= 1
+        let moveTowards head tail = (fst tail + signum (fst head - fst tail), snd tail + signum (snd head - snd tail))
+
+        if List.length heads = 0 then Set.count tailSet
+        else
+            let newHead = List.head heads
+            let newRope = List.scan (fun head tail -> if touches head tail then tail else moveTowards head tail) newHead (List.tail rope)
+            followPath newRope (Set.add (List.last newRope) tailSet) (List.tail heads)
+    
+    let solution ropeSize =
+        followPath (List.replicate ropeSize (0, 0)) Set.empty
+
+    let part1 () = instructions
+                   |> solution 2
+
+    let part2 () = instructions
+                   |> solution 10
\ No newline at end of file