Reputation: 1420
Spoiler-Alert! You'll see a solution for projecteuler.net-Problem 7.
I am sorry if this is a duplicate, but I could not find a question here asking the same.
I compute a sequence of numbers in a function and want to return the nth number.
let isPrime x =
{2..x/2}
|> Seq.exists (fun e -> x%e=0)
|> not
let PrimeNumber nth =
let unfolder a =
a
|> Seq.unfold (fun e -> Some(e, e+1))
|> Seq.find isPrime
|> fun e -> Some(e, e)
2
|> Seq.unfold unfolder
|> Seq.skip (nth-1)
|> Seq.head
let ans = PrimeNumber 10001
ans
will always be 2, but why?
When I evaluate the last expression in PrimeNumber
with nth=10001
then the correct item is returned. Am I missing something?
Upvotes: 0
Views: 507
Reputation: 6324
You want Seq.filter if you need to stick to this solution:
let isPrime x =
{2..x/2}
|> Seq.exists (fun e -> x%e=0)
|> not
let PrimeNumber nth =
let unfolder a =
a
|> Seq.unfold (fun e -> Some(e, e+1))
|> Seq.filter isPrime
2
|> unfolder
|> Seq.skip (nth-1)
|> Seq.item 0
let ans = PrimeNumber 100
will give you 541
But as eluded to in the comments that are other more efficient solutions.
Upvotes: 2
Reputation: 641
The issue lies in your use of Seq.find.
Seq.find, from the documentation, returns the first element for which the condition is true. In this case, that is 2.
Therefore, your unfolder expression will simply generate an infinite sequence of 2s, so whatever element you take, it will always be a 2.
To see this, run just this snippet of your code:
2
|> Seq.unfold unfolder
//output: val it : seq<int> = seq [2; 2; 2; 2; ...]
Upvotes: 2