Day 8 #8
@@ -3,6 +3,14 @@ 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
|
||||
@@ -25,22 +33,14 @@ module Arithmetic =
|
||||
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)
|
||||
: {|
|
||||
Hcf : ^a
|
||||
A : ^a
|
||||
B : ^a
|
||||
|}
|
||||
=
|
||||
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)
|
||||
@@ -60,8 +60,8 @@ module Arithmetic =
|
||||
if a = maxA then
|
||||
result
|
||||
else
|
||||
{|
|
||||
{
|
||||
Hcf = result.Hcf
|
||||
A = result.B
|
||||
B = result.A
|
||||
|}
|
||||
}
|
||||
|
@@ -78,31 +78,33 @@ module Day8 =
|
||||
let part2 (s : string) =
|
||||
let data = parse s
|
||||
|
||||
let startingNodes =
|
||||
data.Nodes.Keys
|
||||
|> Seq.choose (fun k -> if k.[k.Length - 1] = 'A' then Some k else None)
|
||||
|> Seq.toArray
|
||||
let startingNodes = ResizeArray ()
|
||||
|
||||
for key in data.Nodes.Keys do
|
||||
if key.[key.Length - 1] = 'A' then
|
||||
startingNodes.Add key
|
||||
|
||||
let periods =
|
||||
startingNodes
|
||||
|> Array.map (fun startNode ->
|
||||
let mutable i = 0
|
||||
let mutable currentNode = startNode
|
||||
let mutable answer = 0ul
|
||||
Array.init
|
||||
startingNodes.Count
|
||||
(fun startNode ->
|
||||
let mutable i = 0
|
||||
let mutable currentNode = startingNodes.[startNode]
|
||||
let mutable answer = 0ul
|
||||
|
||||
while currentNode.[currentNode.Length - 1] <> 'Z' do
|
||||
let instruction = data.Nodes.[currentNode]
|
||||
while currentNode.[currentNode.Length - 1] <> 'Z' do
|
||||
let instruction = data.Nodes.[currentNode]
|
||||
|
||||
if data.Steps.[i] then
|
||||
// "true" is R
|
||||
currentNode <- snd instruction
|
||||
else
|
||||
currentNode <- fst instruction
|
||||
if data.Steps.[i] then
|
||||
// "true" is R
|
||||
currentNode <- snd instruction
|
||||
else
|
||||
currentNode <- fst instruction
|
||||
|
||||
i <- (i + 1) % data.Steps.Length
|
||||
answer <- answer + 1ul
|
||||
i <- (i + 1) % data.Steps.Length
|
||||
answer <- answer + 1ul
|
||||
|
||||
uint64 answer
|
||||
)
|
||||
uint64 answer
|
||||
)
|
||||
|
||||
lcm periods
|
||||
|
@@ -166,6 +166,7 @@ module Program =
|
||||
Path.Combine (dir.FullName, "day8part1.txt") |> File.ReadAllText
|
||||
with :? FileNotFoundException ->
|
||||
Path.Combine (dir.FullName, "day8.txt") |> File.ReadAllText
|
||||
|
||||
sw.Restart ()
|
||||
let part1 = Day8.part1 input
|
||||
sw.Stop ()
|
||||
|
Reference in New Issue
Block a user