rubysl-prime 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd3a6866a24b3b275738de634a876ffa2fb3642e
4
- data.tar.gz: a196c1f0d9552ad62c724e70088e884fba6cb3fb
3
+ metadata.gz: fbbb9827a8bfc7a111a0ef8240e52e81869db0c5
4
+ data.tar.gz: 604e166c4828a6353155aa48ec1b48b3f67a253d
5
5
  SHA512:
6
- metadata.gz: faecbed84cb564c60fd85586d241b9b5f120790414da934d3681e621e55442659ae3fca22fde5ac748fbf7e0a3576958fa2a3de3c52d41673a316600b23666a7
7
- data.tar.gz: a4b28519f03e56553392650f36a011c71233920bcef7974a4694056ded1a8a15031ea0302b8c5fb78f625b76778ad2637343c0c05b1aa141b9e993d2ca979291
6
+ metadata.gz: 74a3eeae52dc5ebe000279d1675be17af2999e8e7f3abe8a086ed4d55eeaa05aa7be15cac238181f36091e10cb5f364f9470a0b6de1d46e9bb37c14442ef83af
7
+ data.tar.gz: 4d9180867d44735bd9c3b5ffa2c4b5d4865cd14e7781ac94f4e27f93e4b6e43dd8640629ce1acc26a105ade480ef665ceeca5b64eecdfd935793bfadc46ceffe
@@ -1,7 +1,14 @@
1
1
  language: ruby
2
2
  env:
3
3
  - RUBYLIB=lib
4
- script: bundle exec mspec
4
+ - RUBYLIB=
5
+ script: mspec spec
5
6
  rvm:
6
- - 1.9.3
7
- - rbx-nightly-19mode
7
+ - 2.0.0
8
+ - rbx-2.2.1
9
+ matrix:
10
+ exclude:
11
+ - rvm: 2.0.0
12
+ env: RUBYLIB=lib
13
+ - rvm: rbx-2.2.1
14
+ env: RUBYLIB=
@@ -71,20 +71,20 @@ end
71
71
  #
72
72
  # A "generator" provides an implementation of enumerating pseudo-prime
73
73
  # numbers and it remembers the position of enumeration and upper bound.
74
- # Furthermore, it is a external iterator of prime enumeration which is
75
- # compatible to an Enumerator.
74
+ # Furthermore, it is an external iterator of prime enumeration which is
75
+ # compatible with an Enumerator.
76
76
  #
77
77
  # +Prime+::+PseudoPrimeGenerator+ is the base class for generators.
78
78
  # There are few implementations of generator.
79
79
  #
80
80
  # [+Prime+::+EratosthenesGenerator+]
81
- # Uses eratosthenes's sieve.
81
+ # Uses eratosthenes' sieve.
82
82
  # [+Prime+::+TrialDivisionGenerator+]
83
83
  # Uses the trial division method.
84
84
  # [+Prime+::+Generator23+]
85
- # Generates all positive integers which is not divided by 2 nor 3.
85
+ # Generates all positive integers which are not divisible by either 2 or 3.
86
86
  # This sequence is very bad as a pseudo-prime sequence. But this
87
- # is faster and uses much less memory than other generators. So,
87
+ # is faster and uses much less memory than the other generators. So,
88
88
  # it is suitable for factorizing an integer which is not large but
89
89
  # has many prime factors. e.g. for Prime#prime? .
90
90
 
@@ -133,13 +133,13 @@ class Prime
133
133
  # a parameter.
134
134
  #
135
135
  # +ubound+::
136
- # Upper bound of prime numbers. The iterator stops after
136
+ # Upper bound of prime numbers. The iterator stops after it
137
137
  # yields all prime numbers p <= +ubound+.
138
138
  #
139
139
  # == Note
140
140
  #
141
- # +Prime+.+new+ returns a object extended by +Prime+::+OldCompatibility+
142
- # in order to compatibility to Ruby 1.8, and +Prime+#each is overwritten
141
+ # +Prime+.+new+ returns an object extended by +Prime+::+OldCompatibility+
142
+ # in order to be compatible with Ruby 1.8, and +Prime+#each is overwritten
143
143
  # by +Prime+::+OldCompatibility+#+each+.
144
144
  #
145
145
  # +Prime+.+new+ is now obsolete. Use +Prime+.+instance+.+each+ or simply
@@ -191,9 +191,9 @@ class Prime
191
191
  # +value+:: An arbitrary integer.
192
192
  # +generator+:: Optional. A pseudo-prime generator.
193
193
  # +generator+.succ must return the next
194
- # pseudo-prime number in the ascendent
194
+ # pseudo-prime number in the ascending
195
195
  # order. It must generate all prime numbers,
196
- # but may generate non prime numbers.
196
+ # but may also generate non prime numbers too.
197
197
  #
198
198
  # === Exceptions
199
199
  # +ZeroDivisionError+:: when +value+ is zero.
@@ -209,7 +209,7 @@ class Prime
209
209
  #
210
210
  # Prime.prime_division(12) #=> [[2,2], [3,1]]
211
211
  #
212
- def prime_division(value, generator= Prime::Generator23.new)
212
+ def prime_division(value, generator = Prime::Generator23.new)
213
213
  raise ZeroDivisionError if value == 0
214
214
  if value < 0
215
215
  value = -value
@@ -272,7 +272,7 @@ class Prime
272
272
  raise NotImplementedError, "need to define `rewind'"
273
273
  end
274
274
 
275
- # Iterates the given block for each prime numbers.
275
+ # Iterates the given block for each prime number.
276
276
  def each(&block)
277
277
  return self.dup unless block
278
278
  if @ubound
@@ -306,12 +306,13 @@ class Prime
306
306
  # Uses +EratosthenesSieve+.
307
307
  class EratosthenesGenerator < PseudoPrimeGenerator
308
308
  def initialize
309
- @last_prime = nil
309
+ @last_prime_index = -1
310
310
  super
311
311
  end
312
312
 
313
313
  def succ
314
- @last_prime = @last_prime ? EratosthenesSieve.instance.next_to(@last_prime) : 2
314
+ @last_prime_index += 1
315
+ EratosthenesSieve.instance.get_nth_prime(@last_prime_index)
315
316
  end
316
317
  def rewind
317
318
  initialize
@@ -336,11 +337,11 @@ class Prime
336
337
  alias next succ
337
338
  end
338
339
 
339
- # Generates all integer which are greater than 2 and
340
- # are not divided by 2 nor 3.
340
+ # Generates all integers which are greater than 2 and
341
+ # are not divisible by either 2 or 3.
341
342
  #
342
343
  # This is a pseudo-prime generator, suitable on
343
- # checking primality of a integer by brute force
344
+ # checking primality of an integer by brute force
344
345
  # method.
345
346
  class Generator23<PseudoPrimeGenerator
346
347
  def initialize
@@ -418,72 +419,52 @@ class Prime
418
419
  end
419
420
  end
420
421
 
421
- # Internal use. An implementation of eratosthenes's sieve
422
+ # Internal use. An implementation of eratosthenes' sieve
422
423
  class EratosthenesSieve
423
424
  include Singleton
424
425
 
425
- BITS_PER_ENTRY = 16 # each entry is a set of 16-bits in a Fixnum
426
- NUMS_PER_ENTRY = BITS_PER_ENTRY * 2 # twiced because even numbers are omitted
427
- ENTRIES_PER_TABLE = 8
428
- NUMS_PER_TABLE = NUMS_PER_ENTRY * ENTRIES_PER_TABLE
429
- FILLED_ENTRY = (1 << NUMS_PER_ENTRY) - 1
430
-
431
- def initialize # :nodoc:
432
- # bitmap for odd prime numbers less than 256.
433
- # For an arbitrary odd number n, @tables[i][j][k] is
434
- # * 1 if n is prime,
435
- # * 0 if n is composite,
436
- # where i,j,k = indices(n)
437
- @tables = [[0xcb6e, 0x64b4, 0x129a, 0x816d, 0x4c32, 0x864a, 0x820d, 0x2196].freeze]
426
+ def initialize
427
+ @primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
428
+ # @max_checked must be an even number
429
+ @max_checked = @primes.last + 1
438
430
  end
439
431
 
440
- # returns the least odd prime number which is greater than +n+.
441
- def next_to(n)
442
- n = (n-1).div(2)*2+3 # the next odd number to given n
443
- table_index, integer_index, bit_index = indices(n)
444
- loop do
445
- extend_table until @tables.length > table_index
446
- for j in integer_index...ENTRIES_PER_TABLE
447
- if !@tables[table_index][j].zero?
448
- for k in bit_index...BITS_PER_ENTRY
449
- return NUMS_PER_TABLE*table_index + NUMS_PER_ENTRY*j + 2*k+1 if !@tables[table_index][j][k].zero?
450
- end
451
- end
452
- bit_index = 0
453
- end
454
- table_index += 1; integer_index = 0
455
- end
432
+ def get_nth_prime(n)
433
+ compute_primes while @primes.size <= n
434
+ @primes[n]
456
435
  end
457
436
 
458
437
  private
459
- # for an odd number +n+, returns (i, j, k) such that @tables[i][j][k] represents primarity of the number
460
- def indices(n)
461
- # binary digits of n: |0|1|2|3|4|5|6|7|8|9|10|11|....
462
- # indices: |-| k | j | i
463
- # because of NUMS_PER_ENTRY, NUMS_PER_TABLE
464
-
465
- k = (n & 0b00011111) >> 1
466
- j = (n & 0b11100000) >> 5
467
- i = n >> 8
468
- return i, j, k
469
- end
438
+ def compute_primes
439
+ # max_segment_size must be an even number
440
+ max_segment_size = 1e6.to_i
441
+ max_cached_prime = @primes.last
442
+ # do not double count primes if #compute_primes is interrupted
443
+ # by Timeout.timeout
444
+ @max_checked = max_cached_prime + 1 if max_cached_prime > @max_checked
445
+
446
+ segment_min = @max_checked
447
+ segment_max = [segment_min + max_segment_size, max_cached_prime * 2].min
448
+ root = Integer(Math.sqrt(segment_max).floor)
449
+
450
+ sieving_primes = @primes[1 .. -1].take_while { |prime| prime <= root }
451
+ offsets = Array.new(sieving_primes.size) do |i|
452
+ (-(segment_min + 1 + sieving_primes[i]) / 2) % sieving_primes[i]
453
+ end
470
454
 
471
- def extend_table
472
- lbound = NUMS_PER_TABLE * @tables.length
473
- ubound = lbound + NUMS_PER_TABLE
474
- new_table = [FILLED_ENTRY] * ENTRIES_PER_TABLE # which represents primarity in lbound...ubound
475
- (3..Integer(Math.sqrt(ubound))).step(2) do |p|
476
- i, j, k = indices(p)
477
- next if @tables[i][j][k].zero?
478
-
479
- start = (lbound.div(p)+1)*p # least multiple of p which is >= lbound
480
- start += p if start.even?
481
- (start...ubound).step(2*p) do |n|
482
- _, j, k = indices(n)
483
- new_table[j] &= FILLED_ENTRY^(1<<k)
455
+ segment = ((segment_min + 1) .. segment_max).step(2).to_a
456
+ sieving_primes.each_with_index do |prime, index|
457
+ composite_index = offsets[index]
458
+ while composite_index < segment.size do
459
+ segment[composite_index] = nil
460
+ composite_index += prime
484
461
  end
485
462
  end
486
- @tables << new_table.freeze
463
+
464
+ segment.each do |prime|
465
+ @primes.push prime unless prime.nil?
466
+ end
467
+ @max_checked = segment_max
487
468
  end
488
469
  end
489
470
 
@@ -1,5 +1,5 @@
1
1
  module RubySL
2
2
  module Prime
3
- VERSION = "2.0.0"
3
+ VERSION = "2.0.1"
4
4
  end
5
5
  end
@@ -16,7 +16,10 @@ Gem::Specification.new do |spec|
16
16
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
17
  spec.require_paths = ["lib"]
18
18
 
19
+ spec.required_ruby_version = "~> 2.0"
20
+
19
21
  spec.add_development_dependency "bundler", "~> 1.3"
20
22
  spec.add_development_dependency "rake", "~> 10.0"
21
23
  spec.add_development_dependency "mspec", "~> 1.5"
22
- end
24
+ spec.add_development_dependency "rubysl-prettyprint", "~> 2.0"
25
+ end
metadata CHANGED
@@ -1,57 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubysl-prime
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Shirai
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-05 00:00:00.000000000 Z
11
+ date: 2013-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: mspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.5'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubysl-prettyprint
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
55
69
  description: Ruby standard library prime.
56
70
  email:
57
71
  - brixen@gmail.com
@@ -59,8 +73,8 @@ executables: []
59
73
  extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
- - .gitignore
63
- - .travis.yml
76
+ - ".gitignore"
77
+ - ".travis.yml"
64
78
  - Gemfile
65
79
  - LICENSE
66
80
  - README.md
@@ -93,12 +107,12 @@ require_paths:
93
107
  - lib
94
108
  required_ruby_version: !ruby/object:Gem::Requirement
95
109
  requirements:
96
- - - '>='
110
+ - - "~>"
97
111
  - !ruby/object:Gem::Version
98
- version: '0'
112
+ version: '2.0'
99
113
  required_rubygems_version: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - '>='
115
+ - - ">="
102
116
  - !ruby/object:Gem::Version
103
117
  version: '0'
104
118
  requirements: []
@@ -121,3 +135,4 @@ test_files:
121
135
  - spec/prime_spec.rb
122
136
  - spec/shared/next.rb
123
137
  - spec/succ_spec.rb
138
+ has_rdoc: