Advertisement
Guest User

Primes

a guest
Jun 9th, 2011
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 2.12 KB | None | 0 0
  1. open System.Threading
  2. open System.Numerics
  3.  
  4. let waitFor o= ignore(Monitor.Wait o)
  5. let wakeWaiters = Monitor.PulseAll
  6.  
  7. /// Make a named thread that runs f
  8. let mkThread name f = Thread (ThreadStart f, Name=name)
  9. /// Make a named thread and start it immediately
  10. let startThread name f = (mkThread name f).Start()
  11.  
  12.  
  13. let primes :ref<Set<bigint>>= ref (Set.singleton 2I) //start with just the prime 2, listed //TODO: this is kinda a messy way to say 2
  14.  
  15. type bigOddIntGen (min:bigint) =
  16.     let next=ref min
  17.     member this.Next = lock this <| fun () ->
  18.         let v = !next
  19.         next:= v + 2I
  20.         v
  21.  
  22. let unchecked = bigOddIntGen(3I)
  23.  
  24. ///a lockable object for printign to the screen
  25. let stdout = ref ()
  26.  
  27. let rec primeMaker maxVal :unit=
  28.     let isPrime n =
  29.         ///returns possible prime divisors of the nukmber n (won't return til it has all of them)
  30.         let possibleDivisors = lock primes <| fun () ->
  31.             while (!primes |> Set.maxElement) * (2I) < n  do //(Set.exists (fun p -> (bigint 2)*p>=n) (!primes)) do
  32.                 printfn "**********************";
  33.                 waitFor primes
  34.             Set.filter (fun p -> p<=n/(2I)) (!primes)
  35.  
  36.         not <| Set.exists (fun p -> n % p = bigint.Zero) possibleDivisors
  37.  
  38.    
  39.     let printer name n=
  40.         let pf () = lock stdout <| fun () ->
  41.             ignore <| printfn "%s found prime: %s" name (n.ToString())
  42.             //HACK: BigInt>ToSting is broken: only preserves 50 digits. there is a work around but not using it
  43.         pf ()
  44.         //startThread "printer" pf;
  45.        
  46.  
  47.     ///Adds a p to out set of primes
  48.     let addPrime p = lock primes <| fun () ->
  49.         primes:= (!primes).Add p;
  50.         wakeWaiters primes
  51.  
  52.     let x = unchecked.Next
  53.     if maxVal<>None && x>maxVal.Value then ();
  54.     elif isPrime x then
  55.         printer Thread.CurrentThread.Name x;
  56.         addPrime x;
  57.     primeMaker maxVal;
  58.    
  59.  
  60. //primeMaker "t1" (BigInteger(System.Int32.MaxValue))
  61.  
  62. let pm=fun () -> primeMaker <| Some (BigInteger(System.Int32.MaxValue))
  63.  
  64. for i in [1..54] do
  65.     let name = sprintf "t%d" i
  66.     startThread name pm;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement