summary refs log tree commit diff stats
path: root/solutions
diff options
context:
space:
mode:
authorBrian Chu <brianmchu42@gmail.com>2022-12-13 00:34:46 -0800
committerBrian Chu <brianmchu42@gmail.com>2022-12-13 00:34:46 -0800
commit6eb34aa6152415e6db96b45456bfaefd242c1b0d (patch)
treeda55480d9653d93a5e15fe8213bb975f2eae1a7c /solutions
parentcdabc548b41b1990393b6d563c813352bb8dbf01 (diff)
downloadAdventOfCode2022-6eb34aa6152415e6db96b45456bfaefd242c1b0d.tar.gz
solution for day 9
Diffstat (limited to 'solutions')
-rw-r--r--solutions/day9.fs39
1 files changed, 39 insertions, 0 deletions
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