diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj index 4ae55e8..10eaced 100644 --- a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj +++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj @@ -20,6 +20,7 @@ + diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day10.fs b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day10.fs new file mode 100644 index 0000000..ed199ec --- /dev/null +++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day10.fs @@ -0,0 +1,133 @@ +namespace AdventOfCode2023 + +#if DEBUG +#else +#nowarn "9" +#endif + +open System + +[] +module Day10 = + + type Pipe = + | Empty = '.' + | NorthSouth = '|' + | EastWest = '-' + | NorthEast = 'L' + | NorthWest = '7' + | SouthEast = 'F' + | SouthWest = '7' + | Animal = 'S' + + /// Returns first the line number, then the position within that line. + /// lineLength includes the newline, as does pos. + let inline toRowAndCol (lineLength : int) (lineCount : int) (pos : int) : struct (int * int) = + let lineNum = pos / lineLength + let withinLine = pos % lineLength + struct (lineNum, withinLine) + + let inline ofRowAndCol (lineLength : int) (lineCount : int) (lineNum : int) (col : int) : int = + lineNum * lineLength + col + + let inline nextPoint (s : ReadOnlySpan) (lineLength : int) (lineCount : int) (currPos : int) (prevPos : int) = + let struct (currLineNum, currCol) = toRowAndCol lineLength lineCount currPos + let struct (prevLineNum, prevCol) = toRowAndCol lineLength lineCount prevPos + match s.[currPos] with + | '|' -> + if prevLineNum < currLineNum then + ofRowAndCol lineLength lineCount (currLineNum + 1) currCol + else + ofRowAndCol lineLength lineCount (currLineNum - 1) currCol + | '-' -> + if prevCol < currCol then + ofRowAndCol lineLength lineCount currLineNum (currCol + 1) + else + ofRowAndCol lineLength lineCount currLineNum (currCol - 1) + | 'L' -> + if prevLineNum = currLineNum then + ofRowAndCol lineLength lineCount (currLineNum - 1) currCol + else + ofRowAndCol lineLength lineCount currLineNum (currCol + 1) + | '7' -> + if prevLineNum = currLineNum then + ofRowAndCol lineLength lineCount (currLineNum + 1) currCol + else + ofRowAndCol lineLength lineCount currLineNum (currCol - 1) + | 'F' -> + if prevLineNum = currLineNum then + ofRowAndCol lineLength lineCount (currLineNum + 1) currCol + else + ofRowAndCol lineLength lineCount currLineNum (currCol + 1) + | 'J' -> + if prevLineNum = currLineNum then + ofRowAndCol lineLength lineCount (currLineNum - 1) currCol + else + ofRowAndCol lineLength lineCount currLineNum (currCol - 1) + | c -> failwithf "unrecognised: %c" c + + let part1 (s : string) = + let s = s.AsSpan() + let lineCount = s.Count '\n' + let lineLength = (s.IndexOf '\n' + 1) + let startPos = s.IndexOf 'S' + + let struct (startLine, startCol) = toRowAndCol lineLength lineCount startPos + let mutable distance = 1 + let mutable prevPointA = startPos + let mutable prevPointB = startPos + + let mutable pointA = + let pos = ofRowAndCol lineLength lineCount startLine (startCol - 1) + match s.[pos] with + | '-' + | 'L' + | 'F' -> pos + | _ -> + + let pos = ofRowAndCol lineLength lineCount startLine (startCol + 1) + match s.[pos] with + | '-' + | 'J' + | '7' -> pos + | _ -> + + ofRowAndCol lineLength lineCount (startLine + 1) startCol + + let mutable pointB = + let pos = ofRowAndCol lineLength lineCount (startLine - 1) startCol + match s.[pos] with + | '|' + | '7' + | 'F' -> pos + | _ -> + + let pos = ofRowAndCol lineLength lineCount (startLine + 1) startCol + match s.[pos] with + | '|' + | 'L' + | 'J' -> pos + | _ -> + + let pos = ofRowAndCol lineLength lineCount startLine (startCol + 1) + match s.[pos] with + | '-' + | 'J' + | '7' -> pos + | _ -> ofRowAndCol lineLength lineCount startLine (startCol - 1) + + while pointA <> pointB do + let currentA = pointA + pointA <- nextPoint s lineLength lineCount pointA prevPointA + prevPointA <- currentA + + let currentB = pointB + pointB <- nextPoint s lineLength lineCount pointB prevPointB + prevPointB <- currentB + + distance <- distance + 1 + + distance + + let part2 (s : string) = + 0 diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs index f69ac90..3343dae 100644 --- a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs +++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs @@ -195,6 +195,22 @@ module Program = Console.WriteLine (part2.ToString ()) Console.Error.WriteLine ((1_000.0 * float sw.ElapsedTicks / float Stopwatch.Frequency).ToString () + "ms") + Console.WriteLine "=====Day 10=====" + + do + let input = Path.Combine (dir.FullName, "day10.txt") |> File.ReadAllText + + sw.Restart () + let part1 = Day10.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 = Day10.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 7c324d0..4cef56b 100644 --- a/AdventOfCode2023.FSharp/Test/Test.fsproj +++ b/AdventOfCode2023.FSharp/Test/Test.fsproj @@ -18,6 +18,7 @@ + @@ -29,6 +30,8 @@ + + diff --git a/AdventOfCode2023.FSharp/Test/TestDay10.fs b/AdventOfCode2023.FSharp/Test/TestDay10.fs new file mode 100644 index 0000000..99ee5b7 --- /dev/null +++ b/AdventOfCode2023.FSharp/Test/TestDay10.fs @@ -0,0 +1,102 @@ +namespace AdventOfCode2023.Test + +open AdventOfCode2023 +open NUnit.Framework +open FsUnitTyped +open System.IO + +[] +module TestDay10 = + + let part1Sample1 () = + """..... +.S-7. +.|.|. +.L-J. +..... +""" + |> Day10.part1 |> shouldEqual 4 + + + [] + let part1Sample () = + Assembly.getEmbeddedResource typeof.Assembly "day10part1.txt" + |> Day10.part1 |> shouldEqual 8 + + [] + let part2Sample1 () = + """........... +.S-------7. +.|F-----7|. +.||.....||. +.||.....||. +.|L-7.F-J|. +.|..|.|..|. +.L--J.L--J. +........... +""" + |> Day10.part2 + |> shouldEqual 4 + + [] + let part2Sample2 () = + """.......... +.S------7. +.|F----7|. +.||....||. +.||....||. +.|L-7F-J|. +.|..||..|. +.L--JL--J. +.......... +""" + |> Day10.part2 + |> shouldEqual 4 + + [] + let part2Sample3 () = + """.F----7F7F7F7F-7.... +.|F--7||||||||FJ.... +.||.FJ||||||||L7.... +FJL7L7LJLJ||LJ.L-7.. +L--J.L7...LJS7F-7L7. +....F-J..F7FJ|L7L7L7 +....L7.F7||L7|.L7L7| +.....|FJLJ|FJ|F7|.LJ +....FJL-7.||.||||... +....L---J.LJ.LJLJ... +""" + |> Day10.part2 + |> shouldEqual 8 + + [] + let part2Sample () = + Assembly.getEmbeddedResource typeof.Assembly "day10.txt" + |> Day10.part2 + |> shouldEqual 10 + + [] + let part1Actual () = + let s = + try + File.ReadAllText (Path.Combine (__SOURCE_DIRECTORY__, "../../inputs/day10.txt")) + with + | :? DirectoryNotFoundException + | :? FileNotFoundException -> + Assert.Inconclusive () + failwith "unreachable" + + Day10.part1 s |> shouldEqual 6842 + + [] + let part2Actual () = + let s = + try + File.ReadAllText (Path.Combine (__SOURCE_DIRECTORY__, "../../inputs/day10.txt")) + with + | :? DirectoryNotFoundException + | :? FileNotFoundException -> + Assert.Inconclusive () + failwith "unreachable" + + Day10.part2 s |> shouldEqual -1 diff --git a/AdventOfCode2023.FSharp/Test/samples/day10.txt b/AdventOfCode2023.FSharp/Test/samples/day10.txt new file mode 100644 index 0000000..8f950ae --- /dev/null +++ b/AdventOfCode2023.FSharp/Test/samples/day10.txt @@ -0,0 +1,10 @@ +FF7FSF7F7F7F7F7F---7 +L|LJ||||||||||||F--J +FL-7LJLJ||||||LJL-77 +F--JF--7||LJLJ7F7FJ- +L---JF-JLJ.||-FJLJJ7 +|F|F-JF---7F7-L7L|7| +|FFJF7L7F-JF7|JL---7 +7-L-JL7||F7|L7F-7F7| +L.L7LFJ|||||FJL7||LJ +L7JLJL-JLJLJL--JLJ.L diff --git a/AdventOfCode2023.FSharp/Test/samples/day10part1.txt b/AdventOfCode2023.FSharp/Test/samples/day10part1.txt new file mode 100644 index 0000000..682499d --- /dev/null +++ b/AdventOfCode2023.FSharp/Test/samples/day10part1.txt @@ -0,0 +1,5 @@ +..F7. +.FJ|. +SJ.L7 +|F--J +LJ...