diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj index 10eaced..7c5ca68 100644 --- a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj +++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj @@ -21,6 +21,7 @@ + diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day11.fs b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day11.fs new file mode 100644 index 0000000..6c8c4d6 --- /dev/null +++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day11.fs @@ -0,0 +1,81 @@ +namespace AdventOfCode2023 + +open System + +[] +module Day11 = + + let inline private toRowAndCol (lineLength : int) (pos : int) : struct (int * int) = + let lineNum = pos / lineLength + let withinLine = pos % lineLength + struct (lineNum, withinLine) + + let inline private ofRowAndCol (lineLength : int) (lineNum : int) (col : int) : int = lineNum * lineLength + col + + let part1 (s : string) = + let galaxies = ResizeArray () + let rowsWithoutGalaxies = ResizeArray () + let rowLength = s.IndexOf '\n' + let mutable hasAnyGalaxy = false + let mutable currRowIndex = 0 + let mutable currColIndex = 0 + + for c in s do + if c = '\n' then + if not hasAnyGalaxy then + rowsWithoutGalaxies.Add currRowIndex + + currRowIndex <- currRowIndex + 1 + currColIndex <- 0 + hasAnyGalaxy <- false + elif c = '#' then + hasAnyGalaxy <- true + galaxies.Add (currRowIndex, currColIndex) + currColIndex <- currColIndex + 1 + else + currColIndex <- currColIndex + 1 + + galaxies.Sort (fun (_, c1) (_, c2) -> compare c1 c2) + + let colsWithoutGalaxies = + let result = ResizeArray () + let mutable prevCol = 0 + + for (_, c) in galaxies do + if c > prevCol then + for j = prevCol + 1 to c - 1 do + result.Add j + + prevCol <- c + + result + + let mutable answer = 0 + + for galaxy1 = 0 to galaxies.Count - 1 do + let row1, col1 = galaxies.[galaxy1] + + for galaxy2 = galaxy1 + 1 to galaxies.Count - 1 do + let row2, col2 = galaxies.[galaxy2] + let baseDistance = abs (row1 - row2) + abs (col1 - col2) + + let extraDistance = + let mutable extraDistance = 0 + + for i = 1 + min row1 row2 to max row1 row2 - 1 do + if rowsWithoutGalaxies.Contains i then + extraDistance <- extraDistance + 1 + + for i = 1 + min col1 col2 to max col1 col2 - 1 do + if colsWithoutGalaxies.Contains i then + extraDistance <- extraDistance + 1 + + extraDistance + + answer <- answer + extraDistance + baseDistance + + answer + + let part2 (s : string) = + use s = StringSplitEnumerator.make '\n' s + 0 diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs index 3343dae..218bd1d 100644 --- a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs +++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs @@ -211,6 +211,22 @@ module Program = Console.WriteLine (part2.ToString ()) Console.Error.WriteLine ((1_000.0 * float sw.ElapsedTicks / float Stopwatch.Frequency).ToString () + "ms") + Console.WriteLine "=====Day 11=====" + + do + let input = Path.Combine (dir.FullName, "day11.txt") |> File.ReadAllText + + sw.Restart () + let part1 = Day11.part1 input + sw.Stop () + Console.WriteLine (part1.ToString ()) + Console.Error.WriteLine ((1_000.0 * float sw.ElapsedTicks / float Stopwatch.Frequency).ToString () + "ms") + sw.Restart () + let part2 = Day11.part2 input + sw.Stop () + Console.WriteLine (part2.ToString ()) + Console.Error.WriteLine ((1_000.0 * float sw.ElapsedTicks / float Stopwatch.Frequency).ToString () + "ms") + endToEnd.Stop () Console.Error.WriteLine ( diff --git a/AdventOfCode2023.FSharp/Test/Test.fsproj b/AdventOfCode2023.FSharp/Test/Test.fsproj index b511fbe..9fe6516 100644 --- a/AdventOfCode2023.FSharp/Test/Test.fsproj +++ b/AdventOfCode2023.FSharp/Test/Test.fsproj @@ -19,6 +19,7 @@ + @@ -32,6 +33,7 @@ + diff --git a/AdventOfCode2023.FSharp/Test/TestDay11.fs b/AdventOfCode2023.FSharp/Test/TestDay11.fs new file mode 100644 index 0000000..ffc65c6 --- /dev/null +++ b/AdventOfCode2023.FSharp/Test/TestDay11.fs @@ -0,0 +1,44 @@ +namespace AdventOfCode2023.Test + +open AdventOfCode2023 +open NUnit.Framework +open FsUnitTyped +open System.IO + +[] +module TestDay11 = + + let sample = Assembly.getEmbeddedResource typeof.Assembly "day11.txt" + + [] + let part1Sample () = + sample |> Day11.part1 |> shouldEqual 374 + + [] + let part2Sample () = sample |> Day11.part2 |> shouldEqual -1 + + [] + let part1Actual () = + let s = + try + File.ReadAllText (Path.Combine (__SOURCE_DIRECTORY__, "../../inputs/day11.txt")) + with + | :? DirectoryNotFoundException + | :? FileNotFoundException -> + Assert.Inconclusive () + failwith "unreachable" + + Day11.part1 s |> shouldEqual 9947476 + + [] + let part2Actual () = + let s = + try + File.ReadAllText (Path.Combine (__SOURCE_DIRECTORY__, "../../inputs/day11.txt")) + with + | :? DirectoryNotFoundException + | :? FileNotFoundException -> + Assert.Inconclusive () + failwith "unreachable" + + Day11.part2 s |> shouldEqual -1 diff --git a/AdventOfCode2023.FSharp/Test/TestDay9.fs b/AdventOfCode2023.FSharp/Test/TestDay9.fs index 6d9c969..38b4822 100644 --- a/AdventOfCode2023.FSharp/Test/TestDay9.fs +++ b/AdventOfCode2023.FSharp/Test/TestDay9.fs @@ -15,10 +15,7 @@ module TestDay9 = sample |> Day9.part1 |> shouldEqual 114L [] - let part2Sample () = - Assembly.getEmbeddedResource typeof.Assembly "day9.txt" - |> Day9.part2 - |> shouldEqual 2L + let part2Sample () = sample |> Day9.part2 |> shouldEqual 2L [] let part1Actual () = diff --git a/AdventOfCode2023.FSharp/Test/samples/day11.txt b/AdventOfCode2023.FSharp/Test/samples/day11.txt new file mode 100644 index 0000000..986aad4 --- /dev/null +++ b/AdventOfCode2023.FSharp/Test/samples/day11.txt @@ -0,0 +1,10 @@ +...#...... +.......#.. +#......... +.......... +......#... +.#........ +.........# +.......... +.......#.. +#...#.....