Files
advent-of-code-2023/AdventOfCode2023.FSharp/AdventOfCode2023.FSharp.Lib/Rational.fs
patrick 3b98d704d1
All checks were successful
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/push/all-checks-complete Pipeline was successful
Day 9 (#10)
Went with Lagrange interpolation instead because that seemed easier.

Co-authored-by: Smaug123 <patrick+github@patrickstevens.co.uk>
Reviewed-on: #10
2023-12-09 09:46:17 +00:00

83 lines
2.6 KiB
Forth

namespace AdventOfCode2023
[<Struct>]
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
}
[<RequireQualifiedAccess>]
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