Whilst solving the 12th project euler problem I set about making an infinite sequence to get successive triangular numbers. My first attempt was:
let slowTriangularNumbers =
let rec triangularNumbersFrom n =
seq {
yield seq { 0 .. n } |> Seq.sum
yield! triangularNumbersFrom (n + 1)
}
triangularNumbersFrom 1
This turned out to be very slow - each time getting the next item it had to compute all of the additions leading up to n
.
My next attempt was:
let fasterTriangularNumbers =
let cache = System.Collections.Generic.Dictionary<int, int>()
cache.[0] <- 0
let rec triangularNumbersFrom n =
seq {
cache.[n] <- cache.[n - 1] + n
yield cache.[n]
yield! triangularNumbersFrom (n + 1)
}
triangularNumbersFrom 1
Introducing the mutable dictionary has speeded it up considerably, but is this normal to have a mutable collection, or is there another way I could have represented state?
He made the world of men and things his study, learned to write his mother-tongue with idiomatic conciseness, and nourished his imagination on the masterpieces of the Romans. The sounds of a computer executing these machine operations is a completely idiomatic digital sound.
I think this is more idiomatic:
Seq.unfold (fun (i, n) -> Some(n, (i+1, n+i))) (2, 1)
You might prefer this alternative:
seq { 2 .. System.Int32.MaxValue }
|> Seq.scan (+) 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With