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...