Day 8 (#8)
Blown way through my time budget and there's a bunch of low hanging fruit (data dependencies in LCM, for example) but I'm late for work. Co-authored-by: Smaug123 <patrick+github@patrickstevens.co.uk> Reviewed-on: #8
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
namespace AdventOfCode2023
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module Arithmetic =
|
||||
|
||||
[<Struct>]
|
||||
type EuclidResult<'a> =
|
||||
{
|
||||
Hcf : 'a
|
||||
A : 'a
|
||||
B : 'a
|
||||
}
|
||||
|
||||
/// Compute floor(sqrt(i)).
|
||||
let inline sqrt (i : ^a) =
|
||||
if i <= LanguagePrimitives.GenericOne then
|
||||
i
|
||||
else
|
||||
let rec go start =
|
||||
let next = start + LanguagePrimitives.GenericOne
|
||||
let sqr = next * next
|
||||
|
||||
if sqr < LanguagePrimitives.GenericZero then
|
||||
// Overflow attempted, so the sqrt is between start and next
|
||||
start
|
||||
elif i < sqr then
|
||||
start
|
||||
elif i = sqr then
|
||||
next
|
||||
else
|
||||
go next
|
||||
|
||||
go LanguagePrimitives.GenericOne
|
||||
|
||||
/// Find Hcf, A, B s.t. A * a + B * b = Hcf, and Hcf is the highest common factor of a and b.
|
||||
let inline euclideanAlgorithm (a : ^a) (b : ^a) : EuclidResult< ^a > =
|
||||
let rec go rMin1 r sMin1 s tMin1 t =
|
||||
if r = LanguagePrimitives.GenericZero then
|
||||
{
|
||||
Hcf = rMin1
|
||||
A = sMin1
|
||||
B = tMin1
|
||||
}
|
||||
else
|
||||
let newQ = rMin1 / r
|
||||
go r (rMin1 - newQ * r) s (sMin1 - newQ * s) t (tMin1 - newQ * t)
|
||||
|
||||
let maxA = max a b
|
||||
let minB = min a b
|
||||
|
||||
let result =
|
||||
go
|
||||
maxA
|
||||
minB
|
||||
LanguagePrimitives.GenericOne
|
||||
LanguagePrimitives.GenericZero
|
||||
LanguagePrimitives.GenericZero
|
||||
LanguagePrimitives.GenericOne
|
||||
|
||||
if a = maxA then
|
||||
result
|
||||
else
|
||||
{
|
||||
Hcf = result.Hcf
|
||||
A = result.B
|
||||
B = result.A
|
||||
}
|
Reference in New Issue
Block a user