diff options
Diffstat (limited to 'solutions/day13.fs')
-rw-r--r-- | solutions/day13.fs | 53 |
1 files changed, 53 insertions, 0 deletions
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 |