summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Program.fs2
-rw-r--r--solutions/day13.fs53
2 files changed, 55 insertions, 0 deletions
diff --git a/Program.fs b/Program.fs
index f7c7db5..7acfc6c 100644
--- a/Program.fs
+++ b/Program.fs
@@ -32,5 +32,7 @@ match (day, part) with
 | (11, 2) -> printf $"{Day11.part2 ()}\n"
 | (12, 1) -> printf $"{Day12.part1 ()}\n"
 | (12, 2) -> printf $"{Day12.part2 ()}\n"
+| (13, 1) -> printf $"{Day13.part1 ()}\n"
+| (13, 2) -> printf $"{Day13.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/day13.fs b/solutions/day13.fs
new file mode 100644
index 0000000..6caed93
--- /dev/null
+++ b/solutions/day13.fs
@@ -0,0 +1,53 @@
+module Solutions.Day13
+open System
+open System.IO
+open System.Text.Json.Nodes
+
+type Packet =
+| PList of Packet array
+| PInt of int
+
+let rec parsePacket (p: JsonNode) =
+    match p with
+    | :? JsonArray as a -> a |> Seq.map parsePacket |> Array.ofSeq |> PList
+    | :? JsonValue as v -> v.GetValue<int>() |> PInt
+    | _ -> failwith "shouldn't happen"
+
+let rec comparePackets (left: Packet) (right: Packet) =
+    match left, right with
+    | PInt l, PInt r when l < r -> -1
+    | PInt l, PInt r when l > r -> 1
+    | PInt _, PInt _ -> 0
+    | PInt _, PList _ -> comparePackets (PList [|left|]) right
+    | PList _, PInt _ -> comparePackets left (PList [|right|])
+    | PList l, PList r ->
+        (l, r) 
+        ||> Seq.fold2 (fun acc a b ->
+                        match acc with
+                        | 0 -> comparePackets a b
+                        | x -> x) 0
+        |> function
+        | 0 when l.Length < r.Length -> -1
+        | 0 when l.Length > r.Length -> 1
+        | x -> x
+
+
+let input = File.ReadAllLines("inputs/day13.txt") 
+            |> Seq.filter (fun x -> not <| String.IsNullOrEmpty x) 
+            |> Seq.map (fun x -> JsonNode.Parse x |> parsePacket)
+
+let part1 () = input
+               |> Seq.chunkBySize 2
+               |> Seq.map (fun x -> comparePackets x[0] x[1])
+               |> Seq.indexed
+               |> Seq.map (fun (index, compare) -> if compare = -1 then index + 1 else 0)
+               |> Seq.sum
+
+let part2 () = 
+    let divider2 = PList [| PList [| PInt 2 |] |]
+    let divider6 = PList [| PList [| PInt 6 |] |]
+    let input' = Seq.append input [|divider2; divider6|]
+    let sorted = Seq.sortWith comparePackets input'
+    let d2Index = Seq.findIndex ((=) divider2) sorted |> (+) 1
+    let d6Index = Seq.findIndex ((=) divider6) sorted |> (+) 1
+    d2Index * d6Index
\ No newline at end of file