Generating an infinite set of numbers - f#

I'm trying to make a prime number generator which should be able to return a sequence of prime numbers up to the nth number. Now I figured there should be a more elegant way to do this with sequences besides my current solution which feels a bit verbose and I had to use mutables.
0
|> Seq.unfold (fun x -> if isPrime x
then Some(x, x + 1)
else
let mutable y = x
while isPrime y <> true do
y <- y + 1
Some(y, y + 1))
|> Seq.take(n)

A simple solution using filter
let t = Seq.initInfinite id |> Seq.filter isPrime |> Seq.take n

just for completeness see this MSDN treatment of sequences. It includes this isPrime definition
let isPrime n =
let rec check i =
i > n/2 || (n % i <> 0 && check (i + 1))
check 2
let t2 n = seq { for n in 1..100 do if isPrime n then yield n }
t2 10

Related

Taylor series via F#

I'm trying to write Taylor series in F#.
Have a look at my code
let rec iter a b f i =
if a > b then i;
else f a (iter (a+1) b f i)
let sum a b = iter a b (+) 0 // from 0
// e^x = 1 + x + (x^2)/2 + ... (x^n)/n! + ...
let fact n = iter 1 n (*) 1 // factorial
let pow x n = iter 1 n (fun n acc -> acc * x) 1
let exp x =
iter 0 x
(fun n acc ->
acc + (pow x n) / float (fact n)) 0
In the last row I am trying cast int fact n to float, but seems like I'm wrong because this code isn't compileable :(
Am I doing the right algorithm?
Can I call my code functional-first?
The code doesn't compile, because:
You're trying to divide an integer pow x n by a float. Division has to have operands of the same type.
You're specifying the terminal case of the wrong type. Literal 0 is integer. If you want float zero, use 0.0 or abbreviated 0.
Try this:
let exp x =
iter 0 x
(fun n acc ->
acc + float (pow x n) / float (fact n)) 0.
P.S. In the future, please provide the exact error messages and/or unexpected results that you're getting. Simply saying "doesn't work" is not a good description of a problem.

F#: Want to reinitialize enumerator

I have a sequence of prime number divisors that I want to iterate over for each prime candidate. I use GetEnumerator() MoveNext() and Current. I can't reinitialize the enumerator to start from the beginning. I tried Reset(), which compiled, but gives a runtime error of not implemented.
I am using F# 2.0 Interactive build 4.0.40219.1
Any suggestions?
Regards,
Doug
To clarify the problem: For each prime candidate N I want to iterate thru the prime divisors sequence (up to approx sqrt N) and completely factor N or determine if it is prime. Using the GetEnumerator, MoveNext, Current approach works for the first prime candidate, but on the second prime candidate I want to iterate on my divisors sequence from the beginning. It appears that the only way to do this is to create a new iterator (which is awkward for a large number of prime candidates) or create a new prime sequence (which I don't want to do).
The suggestion of using something like "divisors in seqPrimes" appears to exhaust all divisors before stopping, but I want to stop as soon as a prime divisor divides the prime candidate.
If there is an error in my logic in the above statements, please let me know.
I investigated Seq.cache, and this worked for me. The resulting code follows:
// Recursive isprime function (modified from MSDN)
let isPrime n =
let rec check i =
i > n/2 || (n % i <> 0 && check (i + 2))
if n = 2 then true
elif (n%2) = 0 then false
else check 3
let seqPrimes = seq { for n in 2 .. 100000 do if isPrime n then yield n }
// Cache the sequence to avoid recomputing the sequence elements.
let cachedSeq = Seq.cache seqPrimes
// find the divisors of n (or determine prime) using the seqEnum enumerator
let rec testPrime n (seqEnum:System.Collections.Generic.IEnumerator<int>) =
if n = 1 then printfn "completely factored"
else
let nref = ref n
if seqEnum.MoveNext() then
let divisor = seqEnum.Current
//printfn "trial divisor %A" divisor
if divisor*divisor > n then printfn "prime %A" !nref
else
while ((!nref % divisor) = 0) do
printfn "divisor %A" divisor
nref := !nref / divisor
testPrime !nref seqEnum
// test
for x = 1000000 to 1000010 do
printfn "\ndivisors of %d = " x
let seqEnum = cachedSeq.GetEnumerator()
testPrime x seqEnum
seqEnum.Dispose() // not needed
If you mean that the cause of your attempt to reset the Enumerator is the high cost of regenerating your sequence of primes you may consider caching your sequence. This manner of using your sequence would be idiomatic to F#. To show you how to do this I refer you to the following snippet taken from this context:
let rec primes =
Seq.cache <| seq { yield 2; yield! Seq.unfold nextPrime 3 }
and nextPrime n =
if isPrime n then Some(n, n + 2) else nextPrime(n + 2)
and isPrime n =
if n >= 2 then
primes
|> Seq.tryFind (fun x -> n % x = 0 || x * x > n)
|> fun x -> x.Value * x.Value > n
else false
You may play with this snippet to see that the penalty of re-enumeration here gets negligible.
Talking of Reset() method of IEnumerator, I recall that it is not implemented in current F#, i.e. throws System.NotSupportedException. See MSDN reference for justification.
ADDITION:
In order to test it with the test you've suggested below:
for x in [1000000..1000010] do
printfn "\ndivisors of %d" x
primes
|> Seq.takeWhile ((>) (int(sqrt(float x))))
|> Seq.iter (fun n -> if x%n = 0 then printf "%d " n)
On my laptop test execution takes mere 3ms.

F# Using recursive lists

My code (below) falls over with a stack overflow exception. Im assuming F# isnt like haskell and dosent play well with recursive lists. Whats the correct way of dealing with recursive lists like this in F# ? Should i pass it an int so it has a determined size?
let rec collatz num =
match num with
|x when x % 2 = 0 ->num :: collatz (x/2)
|x -> num :: collatz ((x * 3) + 1)
let smallList = collatz(4) |> Seq.take(4)
For an infinite list like this, you want to return a sequence. Sequences are lazy; lists are not.
let rec collatz num =
seq {
yield num
match num with
| x when x % 2 = 0 -> yield! collatz (x/2)
| x -> yield! collatz ((x * 3) + 1)
}
let smallList =
collatz 4
|> Seq.take 4
|> Seq.toList //[4; 2; 1; 4]
let collatz num =
let next x = if x % 2 = 0 then x / 2 else x * 3 + 1
(num, next num)
|>Seq.unfold (fun (n, x) -> Some (n, (x, next x)))

How to refactor F# code to not use a mutable accumulator?

The following F# code gives the correct answer to Project Euler problem #7:
let isPrime num =
let upperDivisor = int32(sqrt(float num)) // Is there a better way?
let rec evaluateModulo a =
if a = 1 then
true
else
match num % a with
| 0 -> false
| _ -> evaluateModulo (a - 1)
evaluateModulo upperDivisor
let mutable accumulator = 1 // Would like to avoid mutable values.
let mutable number = 2 // ""
while (accumulator <= 10001) do
if (isPrime number) then
accumulator <- accumulator + 1
number <- number + 1
printfn "The 10001st prime number is %i." (number - 1) // Feels kludgy.
printfn ""
printfn "Hit any key to continue."
System.Console.ReadKey() |> ignore
I'd like to avoid the mutable values accumulator and number. I'd also like to refactor the while loop into a tail recursive function. Any tips?
Any ideas on how to remove the (number - 1) kludge which displays the result?
Any general comments about this code or suggestions on how to improve it?
Loops are nice, but its more idiomatic to abstract away loops as much as possible.
let isPrime num =
let upperDivisor = int32(sqrt(float num))
match num with
| 0 | 1 -> false
| 2 -> true
| n -> seq { 2 .. upperDivisor } |> Seq.forall (fun x -> num % x <> 0)
let primes = Seq.initInfinite id |> Seq.filter isPrime
let nthPrime n = Seq.nth n primes
printfn "The 10001st prime number is %i." (nthPrime 10001)
printfn ""
printfn "Hit any key to continue."
System.Console.ReadKey() |> ignore
Sequences are your friend :)
You can refer my F# for Project Euler Wiki:
I got this first version:
let isPrime n =
if n=1 then false
else
let m = int(sqrt (float(n)))
let mutable p = true
for i in 2..m do
if n%i =0 then p <- false
// ~~ I want to break here!
p
let rec nextPrime n =
if isPrime n then n
else nextPrime (n+1)
let problem7 =
let mutable result = nextPrime 2
for i in 2..10001 do
result <- nextPrime (result+1)
result
In this version, although looks nicer, but I still does not early break the loop when the number is not a prime. In Seq module, exist and forall methods support early stop:
let isPrime n =
if n<=1 then false
else
let m = int(sqrt (float(n)))
{2..m} |> Seq.exists (fun i->n%i=0) |> not
// or equivalently :
// {2..m} |> Seq.forall (fun i->n%i<>0)
Notice in this version of isPrime, the function is finally mathematically correct by checking numbers below 2.
Or you can use a tail recursive function to do the while loop:
let isPrime n =
let m = int(sqrt (float(n)))
let rec loop i =
if i>m then true
else
if n%i = 0 then false
else loop (i+1)
loop 2
A more functional version of problem7 is to use Seq.unfold to generate an infinite prime sequence and take nth element of this sequence:
let problem7b =
let primes =
2 |> Seq.unfold (fun p ->
let next = nextPrime (p+1) in
Some( p, next ) )
Seq.nth 10000 primes
Here's my solution, which uses a tail-recursive loop pattern which always allows you to avoid mutables and gain break functionality: http://projecteulerfun.blogspot.com/2010/05/problem-7-what-is-10001st-prime-number.html
let problem7a =
let isPrime n =
let nsqrt = n |> float |> sqrt |> int
let rec isPrime i =
if i > nsqrt then true //break
elif n % i = 0 then false //break
//loop while neither of the above two conditions are true
//pass your state (i+1) to the next call
else isPrime (i+1)
isPrime 2
let nthPrime n =
let rec nthPrime i p count =
if count = n then p //break
//loop while above condition not met
//pass new values in for p and count, emulating state
elif i |> isPrime then nthPrime (i+2) i (count+1)
else nthPrime (i+2) p count
nthPrime 1 1 0
nthPrime 10001
Now, to specifically address some of the questions you had in your solution.
The above nthPrime function allows you to find primes at an arbitrary position, this is how it would look adapted to your approach of finding specifically the 1001 prime, and using your variable names (the solution is tail-recursive and doesn't use mutables):
let prime1001 =
let rec nthPrime i number accumulator =
if accumulator = 1001 then number
//i is prime, so number becomes i in our next call and accumulator is incremented
elif i |> isPrime then prime1001 (i+2) i (accumulator+1)
//i is not prime, so number and accumulator do not change, just advance i to the next odd
else prime1001 (i+2) number accumulator
prime1001 1 1 0
Yes, there is a better way to do square roots: write your own generic square root implementation (reference this and this post for G implementation):
///Finds the square root (integral or floating point) of n
///Does not work with BigRational
let inline sqrt_of (g:G<'a>) n =
if g.zero = n then g.zero
else
let mutable s:'a = (n / g.two) + g.one
let mutable t:'a = (s + (n / s)) / g.two
while t < s do
s <- t
let step1:'a = n/s
let step2:'a = s + step1
t <- step2 / g.two
s
let inline sqrtG n = sqrt_of (G_of n) n
let sqrtn = sqrt_of gn //this has suffix "n" because sqrt is not strictly integral type
let sqrtL = sqrt_of gL
let sqrtI = sqrt_of gI
let sqrtF = sqrt_of gF
let sqrtM = sqrt_of gM

Project Euler Problem 27 in F#

I've been trying to work my way through Problem 27 of Project Euler, but this one seems to be stumping me. Firstly, the code is taking far too long to run (a couple of minutes maybe, on my machine, but more importantly, it's returning the wrong answer though I really can't spot anything wrong with the algorithm after looking through it for a while.
Here is my current code for the solution.
/// Checks number for primality.
let is_prime n =
[|1 .. 2 .. sqrt_int n|] |> Array.for_all (fun x -> n % x <> 0)
/// Memoizes a function.
let memoize f =
let cache = Dictionary<_, _>()
fun x ->
let found, res = cache.TryGetValue(x)
if found then
res
else
let res = f x
cache.[x] <- res
res
/// Problem 27
/// Find a quadratic formula that produces the maximum number of primes for consecutive values of n.
let problem27 n =
let is_prime_mem = memoize is_prime
let range = [|-(n - 1) .. n - 1|]
let natural_nums = Seq.init_infinite (fun i -> i)
range |> Array.map (fun a -> (range |> Array.map (fun b ->
let formula n = n * n + a * n + b
let num_conseq_primes = natural_nums |> Seq.map (fun n -> (n, formula n))
|> Seq.find (fun (n, f) -> not (is_prime_mem f)) |> fst
(a * b, num_conseq_primes)) |> Array.max_by snd)) |> Array.max_by snd |> fst
printn_any (problem27 1000)
Any tips on how to a) get this algorithm actually returning the right answer (I think I'm at least taking a workable approach) and b) improve the performance, as it clearly exceeds the "one minute rule" set out in the Project Euler FAQ. I'm a bit of a newbie to functional programming, so any advice on how I might consider the problem with a more functional solution in mind would also be appreciated.
Two remarks:
You may take advantage of the fact that b must be prime. This follows from the fact that the problem asks for the longest sequence of primes for n = 0, 1, 2, ...
So, formula(0) must be prime to begin with , but formula(0) = b, therefore, b must be prime.
I am not an F# programmer, but it seems to me that the code does not try n= 0 at all. This, of course, does not meet the problem's requirement that n must start from 0, therefore there are neglectable chances a correct answer could be produced.
Right, after a lot of checking that all the helper functions were doing what they should, I've finally reached a working (and reasonably efficient) solution.
Firstly, the is_prime function was completely wrong (thanks to Dimitre Novatchev for making me look at that). I'm not sure quite how I arrived at the function I posted in the original question, but I had assumed it was working since I'd used it in previous problems. (Most likely, I had just tweaked it and broken it since.) Anyway, the working version of this function (which crucially returns false for all integers less than 2) is this:
/// Checks number for primality.
let is_prime n =
if n < 2 then false
else [|2 .. sqrt_int n|] |> Array.for_all (fun x -> n % x <> 0)
The main function was changed to the following:
/// Problem 27
/// Find a quadratic formula that produces the maximum number of primes for consecutive values of n.
let problem27 n =
let is_prime_mem = memoize is_prime
let set_b = primes (int64 (n - 1)) |> List.to_array |> Array.map int
let set_a = [|-(n - 1) .. n - 1|]
let set_n = Seq.init_infinite (fun i -> i)
set_b |> Array.map (fun b -> (set_a |> Array.map (fun a ->
let formula n = n * n + a * n + b
let num_conseq_primes = set_n |> Seq.find (fun n -> not (is_prime_mem (formula n)))
(a * b, num_conseq_primes))
|> Array.max_by snd)) |> Array.max_by snd |> fst
The key here to increase speed was to only generate the set of primes between 1 and 1000 for the values of b (using the primes function, my implementation of the Sieve of Eratosthenes method). I also managed to make this code slightly more concise by eliminating the unnecessary Seq.map.
So, I'm pretty happy with the solution I have now (it takes just under a second), though of course any further suggestions would still be welcome...
You could speed up your "is_prime" function by using a probabilistic algorithm. One of the easiest quick algorithms for this is the Miller-Rabin algorithm.
to get rid of half your computations you could also make the array of possible a´s only contain odd numbers
my superfast python solution :P
flag = [0]*204
primes = []
def ifc(n): return flag[n>>6]&(1<<((n>>1)&31))
def isc(n): flag[n>>6]|=(1<<((n>>1)&31))
def sieve():
for i in xrange(3, 114, 2):
if ifc(i) == 0:
for j in xrange(i*i, 12996, i<<1): isc(j)
def store():
primes.append(2)
for i in xrange(3, 1000, 2):
if ifc(i) == 0: primes.append(i)
def isprime(n):
if n < 2: return 0
if n == 2: return 1
if n & 1 == 0: return 0
if ifc(n) == 0: return 1
return 0
def main():
sieve()
store()
mmax, ret = 0, 0
for b in primes:
for a in xrange(-999, 1000, 2):
n = 1
while isprime(n*n + a*n + b): n += 1
if n > mmax: mmax, ret = n, a * b
print ret
main()

Resources