rubysl-prime 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: