Advertisement
Guest User

Untitled

a guest
Jul 29th, 2016
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.25 KB | None | 0 0
  1. public final class PostponedPrimeIterator: IteratorProtocol {
  2.  
  3. private var basePrimes: PostponedPrimeIterator!
  4. private var basePrime = 0
  5. private var basePrimeSquared = 0
  6.  
  7. private var sieve: [Int: Int] = [:]
  8. private var initialPrimes = [2, 3, 5, 7]
  9. private var c = 9 // First candidate after fixed list
  10.  
  11. public func next() -> Int? {
  12.  
  13. if !initialPrimes.isEmpty {
  14. return initialPrimes.removeFirst()
  15. }
  16.  
  17. if c == 9 {
  18. // Create the base prime generator and fetch the first odd prime:
  19. basePrimes = PostponedPrimeIterator()
  20. _ = basePrimes.next()
  21. basePrime = basePrimes.next()!
  22. basePrimeSquared = basePrime * basePrime
  23. assert(c == basePrimeSquared)
  24. }
  25.  
  26. while true {
  27. defer { c += 2 }
  28.  
  29. let factor: Int
  30. if let f = sieve.removeValue(forKey: c) {
  31. // `c` is divisible by `f`
  32. factor = f
  33. } else if c == basePrimeSquared {
  34. // `c` is the square of `p`
  35. factor = basePrime
  36. basePrime = basePrimes.next()!
  37. basePrimeSquared = basePrime * basePrime
  38. } else {
  39. // `c` is a prime number
  40. assert(c < basePrimeSquared)
  41. return c
  42. }
  43.  
  44. // Insert next odd number which is divisiby by `factor` but not present in the sieve:
  45. var j = c + 2 * factor
  46. while sieve[j] != nil {
  47. j += 2 * factor
  48. }
  49. sieve[j] = factor
  50. }
  51. }
  52. }
  53.  
  54. public struct PostponedPrimeSequence: Sequence {
  55. public func makeIterator() -> PostponedPrimeIterator {
  56. return PostponedPrimeIterator()
  57. }
  58. }
  59.  
  60. let p20 = Array(PostponedPrimeSequence().prefix(20))
  61. print(p20) // [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
  62.  
  63. let TERMS = 1_000_000
  64. let startTime = Date()
  65. var gen = PostponedPrimeIterator()
  66. for _ in 1 ..< TERMS { _ = gen.next() }
  67. let p = gen.next()!
  68. let endTime = Date()
  69. let time = endTime.timeIntervalSince(startTime)
  70. print(p, String(format: "%.02f", endTime.timeIntervalSince(startTime)), "sec")
  71. // 15485863 1.26 sec
  72.  
  73. private var basePrimes: PostponedPrimeIterator!
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement