diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj
index e728483..4ae55e8 100644
--- a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj
+++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/AdventOfCode2023.FSharp.Lib.fsproj
@@ -1,24 +1,25 @@
-
- net8.0
- true
-
+
+ net8.0
+ true
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day9.fs b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day9.fs
index 81c2855..7f8c487 100644
--- a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day9.fs
+++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Day9.fs
@@ -1,37 +1,55 @@
namespace AdventOfCode2023
open System
-open System.Collections.Generic
[]
module Day9 =
- let parse (s : string) =
- use mutable lines = StringSplitEnumerator.make '\n' s
+ let extrapolate (isStart : bool) (arr : ResizeArray) =
+ let mutable answer = 0L
+ let pos = if isStart then -1L else int64 arr.Count
- lines.MoveNext () |> ignore
+ for i = 0 to arr.Count - 1 do
+ let mutable product = Rational.ofInt arr.[i]
- let stepsLine = lines.Current.TrimEnd ()
- let steps = Array.zeroCreate stepsLine.Length
+ for j = 0 to arr.Count - 1 do
+ if j <> i then
+ product <- product * Rational.make (pos - int64 j) (int64 i - int64 j)
- for i = 0 to stepsLine.Length - 1 do
- steps.[i] <- (stepsLine.[i] = 'R')
+ answer <- answer + Rational.assertIntegral product
- let dict = Dictionary ()
-
- while lines.MoveNext () do
- if not lines.Current.IsEmpty then
- use mutable line = StringSplitEnumerator.make' ' ' lines.Current
- line.MoveNext () |> ignore
- {
- Steps = steps
- Nodes = dict
- }
+ answer
let part1 (s : string) =
- let data = parse s
+ use s = StringSplitEnumerator.make '\n' s
+ let mutable answer = 0L
+ let arr = ResizeArray ()
+
+ for line in s do
+ arr.Clear ()
+ use line = StringSplitEnumerator.make' ' ' line
+
+ for number in line do
+ let number = Int64.Parse number
+ arr.Add number
+
+ answer <- answer + extrapolate false arr
+
answer
let part2 (s : string) =
- let data = parse s
- 0
+ use s = StringSplitEnumerator.make '\n' s
+ let mutable answer = 0L
+ let arr = ResizeArray ()
+
+ for line in s do
+ arr.Clear ()
+ use line = StringSplitEnumerator.make' ' ' line
+
+ for number in line do
+ let number = Int64.Parse number
+ arr.Add number
+
+ answer <- answer + extrapolate true arr
+
+ answer
diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/EfficientString.fs b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/EfficientString.fs
index fdfc2f4..657adfb 100644
--- a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/EfficientString.fs
+++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/EfficientString.fs
@@ -1,7 +1,6 @@
namespace AdventOfCode2023
open System
-open System.Globalization
open System.Runtime.CompilerServices
type EfficientString = System.ReadOnlySpan
diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Rational.fs b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Rational.fs
new file mode 100644
index 0000000..cc867e8
--- /dev/null
+++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Rational.fs
@@ -0,0 +1,82 @@
+namespace AdventOfCode2023
+
+[]
+type Rational<'a
+ when 'a : (static member (+) : 'a * 'a -> 'a)
+ and 'a : (static member (*) : 'a * 'a -> 'a)
+ and 'a : (static member (/) : 'a * 'a -> 'a)
+ and 'a : (static member (-) : 'a * 'a -> 'a)
+ and 'a : (static member Zero : 'a)
+ and 'a : (static member One : 'a)
+ and 'a : comparison> =
+ {
+ Numerator : 'a
+ Denominator : 'a
+ }
+
+ static member inline (+) (a : Rational<'a>, b : Rational<'a>) =
+ let numerator = a.Numerator * b.Denominator + b.Numerator * a.Denominator
+ let denominator = a.Denominator * b.Denominator
+ let hcf = (Arithmetic.euclideanAlgorithm numerator denominator).Hcf
+
+ {
+ Numerator = numerator / hcf
+ Denominator = denominator / hcf
+ }
+
+ static member inline (*) (a : Rational<'a>, b : Rational<'a>) =
+ let numerator = a.Numerator * b.Numerator
+ let denominator = a.Denominator * b.Denominator
+ let hcf = (Arithmetic.euclideanAlgorithm numerator denominator).Hcf
+
+ {
+ Numerator = numerator / hcf
+ Denominator = denominator / hcf
+ }
+
+[]
+module Rational =
+ let inline ofInt< ^a
+ when 'a : (static member (+) : 'a * 'a -> 'a)
+ and 'a : (static member (*) : 'a * 'a -> 'a)
+ and 'a : (static member (/) : 'a * 'a -> 'a)
+ and 'a : (static member (-) : 'a * 'a -> 'a)
+ and 'a : (static member Zero : 'a)
+ and 'a : (static member One : 'a)
+ and 'a : comparison>
+ (a : 'a)
+ =
+ {
+ Numerator = a
+ Denominator = LanguagePrimitives.GenericOne
+ }
+
+ let inline make< ^a
+ when 'a : (static member (+) : 'a * 'a -> 'a)
+ and 'a : (static member (*) : 'a * 'a -> 'a)
+ and 'a : (static member (/) : 'a * 'a -> 'a)
+ and 'a : (static member (-) : 'a * 'a -> 'a)
+ and 'a : (static member Zero : 'a)
+ and 'a : (static member One : 'a)
+ and 'a : comparison>
+ (numerator : 'a)
+ (denominator : 'a)
+ =
+ let hcf = (Arithmetic.euclideanAlgorithm numerator denominator).Hcf
+
+ {
+ Numerator = numerator / hcf
+ Denominator = denominator / hcf
+ }
+
+ let inline assertIntegral< ^a
+ when 'a : (static member (+) : 'a * 'a -> 'a)
+ and 'a : (static member (*) : 'a * 'a -> 'a)
+ and 'a : (static member (/) : 'a * 'a -> 'a)
+ and 'a : (static member (-) : 'a * 'a -> 'a)
+ and 'a : (static member Zero : 'a)
+ and 'a : (static member One : 'a)
+ and 'a : comparison>
+ (r : Rational<'a>)
+ =
+ r.Numerator
diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.fsproj b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.fsproj
index c59ca02..745dccd 100644
--- a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.fsproj
+++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.fsproj
@@ -1,28 +1,28 @@
-
- Exe
- net8.0
- true
- true
- true
+
+ Exe
+ net8.0
+ true
+ true
+ true
- Speed
- false
+ Speed
+ false
- false
- false
- false
- false
- false
-
+ false
+ false
+ false
+ false
+ false
+
-
-
-
+
+
+
-
-
-
+
+
+
diff --git a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs
index 236c282..f69ac90 100644
--- a/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs
+++ b/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp/Program.fs
@@ -179,6 +179,22 @@ module Program =
Console.WriteLine (part2.ToString ())
Console.Error.WriteLine ((1_000.0 * float sw.ElapsedTicks / float Stopwatch.Frequency).ToString () + "ms")
+ Console.WriteLine "=====Day 9====="
+
+ do
+ let input = Path.Combine (dir.FullName, "day9.txt") |> File.ReadAllText
+
+ sw.Restart ()
+ let part1 = Day9.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 = Day9.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 b6ff897..7c324d0 100644
--- a/AdventOfCode2023.FSharp/Test/Test.fsproj
+++ b/AdventOfCode2023.FSharp/Test/Test.fsproj
@@ -1,45 +1,46 @@
-
- net8.0
+
+ net8.0
- false
- true
-
+ false
+ true
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
diff --git a/AdventOfCode2023.FSharp/Test/TestDay5.fs b/AdventOfCode2023.FSharp/Test/TestDay5.fs
index 2739873..c119d76 100644
--- a/AdventOfCode2023.FSharp/Test/TestDay5.fs
+++ b/AdventOfCode2023.FSharp/Test/TestDay5.fs
@@ -1,6 +1,5 @@
namespace AdventOfCode2023.Test
-open System
open AdventOfCode2023
open NUnit.Framework
open FsUnitTyped
diff --git a/AdventOfCode2023.FSharp/Test/TestDay6.fs b/AdventOfCode2023.FSharp/Test/TestDay6.fs
index 6235479..1119907 100644
--- a/AdventOfCode2023.FSharp/Test/TestDay6.fs
+++ b/AdventOfCode2023.FSharp/Test/TestDay6.fs
@@ -1,6 +1,5 @@
namespace AdventOfCode2023.Test
-open System
open AdventOfCode2023
open NUnit.Framework
open FsUnitTyped
diff --git a/AdventOfCode2023.FSharp/Test/TestDay7.fs b/AdventOfCode2023.FSharp/Test/TestDay7.fs
index 38f91ee..03983e5 100644
--- a/AdventOfCode2023.FSharp/Test/TestDay7.fs
+++ b/AdventOfCode2023.FSharp/Test/TestDay7.fs
@@ -1,6 +1,5 @@
namespace AdventOfCode2023.Test
-open System
open AdventOfCode2023
open NUnit.Framework
open FsUnitTyped
diff --git a/AdventOfCode2023.FSharp/Test/TestDay9.fs b/AdventOfCode2023.FSharp/Test/TestDay9.fs
index ff243f0..6d9c969 100644
--- a/AdventOfCode2023.FSharp/Test/TestDay9.fs
+++ b/AdventOfCode2023.FSharp/Test/TestDay9.fs
@@ -12,15 +12,13 @@ module TestDay9 =
[]
let part1Sample () =
- sample
- |> Day9.part1
- |> shouldEqual 2
+ sample |> Day9.part1 |> shouldEqual 114L
[]
let part2Sample () =
Assembly.getEmbeddedResource typeof.Assembly "day9.txt"
|> Day9.part2
- |> shouldEqual 0
+ |> shouldEqual 2L
[]
let part1Actual () =
@@ -33,7 +31,7 @@ module TestDay9 =
Assert.Inconclusive ()
failwith "unreachable"
- Day8.part1 s |> shouldEqual 0
+ Day9.part1 s |> shouldEqual 1898776583L
[]
let part2Actual () =
@@ -46,4 +44,4 @@ module TestDay9 =
Assert.Inconclusive ()
failwith "unreachable"
- Day8.part2 s |> shouldEqual 0
+ Day9.part2 s |> shouldEqual 1100L
diff --git a/AdventOfCode2023.FSharp/Test/samples/day9.txt b/AdventOfCode2023.FSharp/Test/samples/day9.txt
new file mode 100644
index 0000000..539a763
--- /dev/null
+++ b/AdventOfCode2023.FSharp/Test/samples/day9.txt
@@ -0,0 +1,3 @@
+0 3 6 9 12 15
+1 3 6 10 15 21
+10 13 16 21 30 45