diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day12.fs b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day12.fs index 4a38605..d94af37 100644 --- a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day12.fs +++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day12.fs @@ -8,11 +8,12 @@ open System.Globalization module Day12 = let rec solve - (dict : Dictionary) + (dict : Dictionary) (line : ReadOnlySpan) (groups : IReadOnlyList) + (remainingToFill : int) (currentGroupIndex : int) - : 'a + : uint64 = if line.Length = 0 then if currentGroupIndex = groups.Count then @@ -30,15 +31,7 @@ module Day12 = | true, v -> v | false, _ -> - let remaining = - let mutable remaining = -1 - - for i = currentGroupIndex to groups.Count - 1 do - remaining <- remaining + groups.[i] + 1 - - remaining - - if remaining > line.Length then + if remainingToFill > line.Length then dict.Add ((line.Length, currentGroupIndex), LanguagePrimitives.GenericZero) LanguagePrimitives.GenericZero else @@ -60,10 +53,20 @@ module Day12 = if line.[groups.[currentGroupIndex]] = '#' then LanguagePrimitives.GenericZero else - solve dict (line.Slice (groups.[currentGroupIndex] + 1)) groups (currentGroupIndex + 1) + solve + dict + (line.Slice (groups.[currentGroupIndex] + 1)) + groups + (remainingToFill - groups.[currentGroupIndex] - 1) + (currentGroupIndex + 1) else - solve dict ReadOnlySpan<_>.Empty groups (currentGroupIndex + 1) - | '.' -> solve dict (line.Slice 1) groups currentGroupIndex + solve + dict + ReadOnlySpan<_>.Empty + groups + (remainingToFill - groups.[currentGroupIndex] - 1) + (currentGroupIndex + 1) + | '.' -> solve dict (line.Slice 1) groups remainingToFill currentGroupIndex | '?' -> let afterMark = line.IndexOfAnyExcept ('?', '#') @@ -75,10 +78,10 @@ module Day12 = // this group *is* filled in, contradiction LanguagePrimitives.GenericZero else - solve dict (line.Slice afterMark) groups currentGroupIndex + solve dict (line.Slice afterMark) groups remainingToFill currentGroupIndex else - let ifDot = solve dict (line.Slice 1) groups currentGroupIndex + let ifDot = solve dict (line.Slice 1) groups remainingToFill currentGroupIndex dict.TryAdd ((line.Length - 1, currentGroupIndex), ifDot) |> ignore let ifHash = @@ -100,9 +103,19 @@ module Day12 = then LanguagePrimitives.GenericZero else - solve dict (line.Slice (groups.[currentGroupIndex] + 1)) groups (currentGroupIndex + 1) + solve + dict + (line.Slice (groups.[currentGroupIndex] + 1)) + groups + (remainingToFill - groups.[currentGroupIndex] - 1) + (currentGroupIndex + 1) else - solve dict ReadOnlySpan<_>.Empty groups (currentGroupIndex + 1) + solve + dict + ReadOnlySpan<_>.Empty + groups + (remainingToFill - groups.[currentGroupIndex] - 1) + (currentGroupIndex + 1) ifDot + ifHash | _ -> @@ -117,6 +130,8 @@ module Day12 = let mutable answer = 0uL let arr = ResizeArray () + let dict = Dictionary () + for line in lines do if not line.IsEmpty then arr.Clear () @@ -125,7 +140,16 @@ module Day12 = for int in ints do arr.Add (Int32.Parse (int, NumberStyles.None, CultureInfo.InvariantCulture)) - let solved = solve (Dictionary ()) line arr 0 + let remainingToFill = + let mutable ans = -1 + + for i = 0 to arr.Count - 1 do + ans <- ans + arr.[i] + 1 + + ans + + dict.Clear () + let solved = solve dict line arr remainingToFill 0 answer <- answer + solved answer @@ -136,6 +160,8 @@ module Day12 = let mutable answer = 0uL let arr = ResizeArray () + let dict = Dictionary () + for line in lines do if not line.IsEmpty then arr.Clear () @@ -152,8 +178,16 @@ module Day12 = let line = String.Concat (sliced, '?', sliced, '?', sliced, '?', sliced, '?', sliced) - let solved = solve (Dictionary ()) (line.AsSpan ()) arr 0 - printfn $"%s{line} : %i{solved}" + let remainingToFill = + let mutable ans = -1 + + for i = 0 to arr.Count - 1 do + ans <- ans + arr.[i] + 1 + + ans + + dict.Clear () + let solved = solve dict (line.AsSpan ()) arr remainingToFill 0 answer <- answer + solved answer diff --git a/AdventOfCode2023.FSharp/Test/TestDay12.fs b/AdventOfCode2023.FSharp/Test/TestDay12.fs index 9993a08..a0020ec 100644 --- a/AdventOfCode2023.FSharp/Test/TestDay12.fs +++ b/AdventOfCode2023.FSharp/Test/TestDay12.fs @@ -42,4 +42,4 @@ module TestDay12 = Assert.Inconclusive () failwith "unreachable" - Day12.part2 s |> shouldEqual 0uL + Day12.part2 s |> shouldEqual 3384337640277uL