From 511814f241e2563b543d89cb117ed06bd033d4c7 Mon Sep 17 00:00:00 2001 From: Smaug123 Date: Tue, 12 Dec 2023 08:55:29 +0000 Subject: [PATCH] Part 1 --- .../AdventOfCode2023.FSharp.Lib/Day12.fs | 47 ++++++++++++++++++- AdventOfCode2023.FSharp/Test/TestDay12.fs | 4 +- .../Test/samples/day12.txt | 6 +++ 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day12.fs b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day12.fs index 88ffe27..df5bb30 100644 --- a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day12.fs +++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day12.fs @@ -1,12 +1,57 @@ namespace AdventOfCode2023 +open System +open System.Collections.Generic +open System.Globalization + [] module Day12 = + let rec solve (line : ReadOnlySpan) (groups : IReadOnlyList) (currentGroupIndex : int) = + match line.[0] with + | '#' -> + if currentGroupIndex >= groups.Count then 0 else + let mutable isOk = true + for i = 1 to groups.[currentGroupIndex] - 1 do + if isOk && line.[i] <> '#' && line.[i] <> '?' then + isOk <- false + if not isOk then 0 else + if line.[groups.[currentGroupIndex]] = '#' then 0 else + solve (line.Slice (groups.[currentGroupIndex] + 1)) groups (currentGroupIndex + 1) + | '.' -> + solve (line.Slice 1) groups currentGroupIndex + | '?' -> + let ifDot = solve (line.Slice 1) groups currentGroupIndex + let ifHash = + if currentGroupIndex >= groups.Count then 0 else + let mutable isOk = true + for i = 1 to groups.[currentGroupIndex] - 1 do + if isOk && line.[i] <> '#' && line.[i] <> '?' then + isOk <- false + if not isOk then 0 else + if line.[groups.[currentGroupIndex]] = '#' then 0 else + solve (line.Slice (groups.[currentGroupIndex] + 1)) groups (currentGroupIndex + 1) + ifDot + ifHash + | _ -> + if currentGroupIndex = groups.Count then 1 else 0 + + let part1 (s : string) = use mutable lines = StringSplitEnumerator.make '\n' s - -1 + let mutable answer = 0 + let arr = ResizeArray () + for line in lines do + if not line.IsEmpty then + arr.Clear () + use ints = StringSplitEnumerator.make' ',' (line.Slice (line.IndexOf ' ' + 1)) + for int in ints do + arr.Add (Int32.Parse (int, NumberStyles.None, CultureInfo.InvariantCulture)) + + let solved = solve line arr 0 + answer <- answer + solved + + answer let part2 (s : string) = use mutable lines = StringSplitEnumerator.make '\n' s diff --git a/AdventOfCode2023.FSharp/Test/TestDay12.fs b/AdventOfCode2023.FSharp/Test/TestDay12.fs index 75d84fb..30d412c 100644 --- a/AdventOfCode2023.FSharp/Test/TestDay12.fs +++ b/AdventOfCode2023.FSharp/Test/TestDay12.fs @@ -12,7 +12,7 @@ module TestDay12 = [] let part1Sample () = - sample |> Day12.part1 |> shouldEqual 0 + sample |> Day12.part1 |> shouldEqual 21 [] let part2Sample () = @@ -31,7 +31,7 @@ module TestDay12 = Assert.Inconclusive () failwith "unreachable" - Day12.part1 s |> shouldEqual 0 + Day12.part1 s |> shouldEqual 7402 [] let part2Actual () = diff --git a/AdventOfCode2023.FSharp/Test/samples/day12.txt b/AdventOfCode2023.FSharp/Test/samples/day12.txt index e69de29..e925935 100644 --- a/AdventOfCode2023.FSharp/Test/samples/day12.txt +++ b/AdventOfCode2023.FSharp/Test/samples/day12.txt @@ -0,0 +1,6 @@ +???.### 1,1,3 +.??..??...?##. 1,1,3 +?#?#?#?#?#?#?#? 1,3,1,6 +????.#...#... 4,1,1 +????.######..#####. 1,6,5 +?###???????? 3,2,1