numb 0.72.1 → 0.77.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  coverage
4
4
  doc
5
5
  pkg
6
+ .yardoc
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.72.1
1
+ 0.77.0
data/lib/numb/abundant.rb CHANGED
@@ -12,7 +12,7 @@ class Integer
12
12
  # 345.abundant? #=> false
13
13
  #
14
14
  def abundant?
15
- return false unless self > 0
15
+ return false unless positive?
16
16
  σ > (2 * self)
17
17
  end
18
18
 
data/lib/numb/aspiring.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  class Integer
2
- def aliquot_sequence
2
+ def aliquot_sequence(max_iterations=(self > 100 ? 10 : Math.sqrt(self)))
3
3
  sequence = [self]
4
- max_iterations = Math.sqrt(self).floor
5
- max_iterations.times do |limit|
4
+ max_iterations.floor.times do |limit|
6
5
  divisors = sequence.last.proper_divisors
7
6
  break if divisors.empty?
8
7
  sequence << divisors.reduce(:+)
@@ -12,8 +11,10 @@ class Integer
12
11
  sequence
13
12
  end
14
13
 
15
- def aspiring?
14
+ def aspiring?(max_iterations=10)
16
15
  return false if perfect?
17
- (last = aliquot_sequence.last).to_f.finite? ? last.perfect? : false
16
+ (last = aliquot_sequence(max_iterations).last).to_f.finite? ?
17
+ last.perfect? :
18
+ false
18
19
  end
19
20
  end
data/lib/numb/base.rb ADDED
@@ -0,0 +1,37 @@
1
+ class Integer
2
+ BASE = {
3
+ binary: 2, ternary: 3, quaternary: 4,
4
+ quinary: 5, senary: 6, septenary: 7,
5
+ octal: 8, nonary: 9, decimal: 10,
6
+ undecimal: 11, duodecimal: 12, tridecimal: 13,
7
+ tetradecimal: 14, pentadecimal: 15, hexadecimal: 16,
8
+ septendecimal: 17, decennoctal: 18, decennoval: 19,
9
+ vigesimal: 20, trigesimal: 30, quadragesimal: 40,
10
+ quinquagesimal: 50, sexagesimal: 60, septuagesimal: 70,
11
+ octagesimal: 80, nonagesimal: 90, centesimal: 100,
12
+ millesimal: 1_000
13
+ }
14
+
15
+ def base(base=nil)
16
+ return Hash[BASE.values.map{|b| [b, base(b)]}] unless base
17
+ return '0' if zero?
18
+ base = case base
19
+ when Numeric then base.to_int
20
+ when String, Symbol then BASE[base.downcase.to_sym]
21
+ else nil
22
+ end
23
+ raise ArgumentError unless base and base > 1
24
+ begin
25
+ to_s(base)
26
+ rescue ArgumentError
27
+ chars = [*(0..9)] + [*('a'..'z')]
28
+ (base - chars.size).times { chars.push(chars.last.succ) }
29
+ n, digits = self, []
30
+ until n.zero?
31
+ n, remainder = n.divmod(base)
32
+ digits << chars[remainder]
33
+ end
34
+ digits.reverse.join
35
+ end
36
+ end
37
+ end
@@ -11,7 +11,7 @@ class Integer
11
11
  # 6.deficient? #=> false
12
12
  #
13
13
  def deficient?
14
- return false unless self > 0
14
+ return false unless positive?
15
15
  σ < (2 * self)
16
16
  end
17
17
 
data/lib/numb/happy.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  class Integer
3
3
  def happy?
4
- return false unless self > 0
4
+ return false unless positive?
5
5
  n = self
6
6
  sad = '4 16 37 58 89 145 42 20'
7
7
  seq = ""
data/lib/numb/hilbert.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  class Integer
3
3
  def hilbert?
4
- return false unless self > 0
4
+ return false unless positive?
5
5
  ((self - 1) % 4) == 0
6
6
  end
7
7
  end
@@ -2,7 +2,7 @@
2
2
  class Integer
3
3
  def nivenmorphic?
4
4
  return true if self == 0
5
- return false unless self > 0
5
+ return false unless positive?
6
6
  niven? && self.to_s.end_with?(digital_sum.to_s)
7
7
  end
8
8
  alias :harshadmorphic? :nivenmorphic?
@@ -4,7 +4,7 @@ class Integer
4
4
  return (1..9).any?{|x| parasitic?(x)} if n.nil?
5
5
  return true if (n == 1 && self == 1)
6
6
  return false unless self > 9
7
- raise ArgumentError unless (n > 0 && n < 10)
7
+ raise ArgumentError unless (n.positive? && n < 10)
8
8
  (n*self) == [digits.last, digits[0..-2]].join.to_i
9
9
  end
10
10
  end
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  class Integer
3
3
  def perfect_power?
4
- return false unless self > 0
4
+ return false unless positive?
5
5
  return true if self == 1
6
6
  divisors = self.divisors
7
7
  (2..Math.log2(self)).any? { |pow| divisors.any? {|div| (div ** pow) == self} }
data/lib/numb/polite.rb CHANGED
@@ -2,6 +2,6 @@
2
2
  class Integer
3
3
  def polite?
4
4
  return true if self == 1
5
- politeness > 0
5
+ politeness.positive?
6
6
  end
7
7
  end
@@ -0,0 +1,5 @@
1
+ class Integer
2
+ def positive?
3
+ self > 0
4
+ end
5
+ end
data/lib/numb/powerful.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  class Integer
3
3
  def powerful?
4
- return false unless self > 0
4
+ return false unless positive?
5
5
  divisors = self.divisors
6
6
  divisors.select {|d| d.prime? }.all?{|prime| divisors.include? (prime ** 2)}
7
7
  end
data/lib/numb/pronic.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  class Integer
2
2
  def pronic?
3
- return false unless even? and self >= 0
3
+ return false unless even? and (positive? or zero?)
4
4
  (Math.sqrt(succ).round - Math.sqrt(self).round) == 1
5
5
  end
6
6
  end
data/lib/numb/weird.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  class Integer
3
3
  def weird?
4
- return false unless self > 0
4
+ return false unless positive?
5
5
  return false if odd? && self < (10 ** 17)
6
6
  not semiperfect? and abundant?
7
7
  end
@@ -0,0 +1,6 @@
1
+ class Integer
2
+ def wieferich_prime?
3
+ return false unless prime?
4
+ (2**(self - 1)).modulo(self ** 2) == 1
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ class Integer
2
+ def woodall?
3
+ x = succ
4
+ divisors = x.square? ? x.divisors[0..-2] : x.divisors
5
+ divisors.each_slice(2).any?{|a, b| a == Math.log2(b)}
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class Integer
2
+ def zerofree?
3
+ not to_s.include?('0')
4
+ end
5
+ end
data/lib/numb.rb CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  libs = %w{abundancy abundant achilles almost_perfect almost_prime amicable
4
4
  apocalyptic aspiring augmented_amicable automorphic balanced_prime
5
- binomial biquadratic breeder brown carmichael carol centered_n_gonal
6
- centered_triangular congruum composite coprime core cototient
7
- cube d decagonal deficient dodecagonal dihedral_prime dudeney
8
- economical emrip equidigital extravagant factorial factorion
5
+ base binomial biquadratic breeder brown carmichael carol
6
+ centered_n_gonal centered_triangular congruum composite coprime
7
+ core cototient cube d decagonal deficient dodecagonal dihedral_prime
8
+ dudeney economical emrip equidigital extravagant factorial factorion
9
9
  fermat_pseudoprime fibonacci friendly frugal happy harshad
10
10
  heptagonal hexagonal highly_composite highly_abundant hilbert
11
11
  hyperperfect idoneal impolite integer_p interprime
@@ -14,14 +14,14 @@ libs = %w{abundancy abundant achilles almost_perfect almost_prime amicable
14
14
  mms_pair mobius myriagonal narcissistic next_prev_prime n_gonal
15
15
  nivenmorphic noncototient nth_prime number_of_divisors octagonal
16
16
  ordinal ore parasitic pentagonal perfect perfect_power polite
17
- polydivisible poulet powerful practical prime_count prime_signature
18
- primitive_pseudoperfect primorial pronic proth quarticfree
19
- refactorable repunit rhonda rough self self_descriptive
17
+ polydivisible positive poulet powerful practical prime_count
18
+ prime_signature primitive_pseudoperfect primorial pronic proth
19
+ quarticfree refactorable repunit rhonda rough self self_descriptive
20
20
  semiperfect semiprime smarandache_wellin smith smooth
21
21
  sophie_germain_prime sphenic square square_free sublime
22
22
  sum_of_squares superabundant superperfect totient triangular
23
23
  trimorphic undulating unitary_perfect unitary_divisor untouchable
24
- vampire weird zeisel
24
+ vampire weird wieferich woodall zeisel zerofree
25
25
  }
26
26
 
27
27
  class Integer
@@ -51,11 +51,10 @@ class Integer
51
51
  end
52
52
 
53
53
  def divisors
54
- return @divisors if defined?(@divisors)
55
- return [] unless self >= 0
54
+ return [] unless positive?
56
55
  return [1, self] if prime?
57
- @divisors = (1..Math.sqrt(self).floor).select { |n| (self % n).zero? }.
58
- map {|n| [n, self/n]}.flatten.uniq
56
+ (1..Math.sqrt(self).floor).select { |n| (self % n).zero? }.
57
+ map {|n| [n, self/n]}.flatten.uniq
59
58
  end
60
59
 
61
60
  def sum_of_divisors
data/spec/base_spec.rb ADDED
@@ -0,0 +1,51 @@
1
+ describe Integer, "#base" do
2
+ @base = {
3
+ binary: 2, ternary: 3, quaternary: 4,
4
+ quinary: 5, senary: 6, septenary: 7,
5
+ octal: 8, nonary: 9, decimal: 10,
6
+ undecimal: 11, duodecimal: 12, tridecimal: 13,
7
+ tetradecimal: 14, pentadecimal: 15, hexadecimal: 16,
8
+ septendecimal: 17, decennoctal: 18, decennoval: 19,
9
+ vigesimal: 20, trigesimal: 30, quadragesimal: 40,
10
+ quinquagesimal: 50, sexagesimal: 60, septuagesimal: 70,
11
+ octagesimal: 80, nonagesimal: 90, centesimal: 100,
12
+ millesimal: 1_000
13
+ }
14
+
15
+ @base.each do |base_name, base|
16
+ break if base > 36
17
+ (0..100).to_a.sample(10).each do |n|
18
+ converted = n.to_s(base)
19
+ it "should return #{converted} for #{n} in base #{base}" do
20
+ n.base(base).should == converted
21
+ end
22
+
23
+ it "should return #{converted} for #{n} in #{base_name}" do
24
+ n.base(base_name).should == converted
25
+ end
26
+ end
27
+ end
28
+
29
+ it "should raise ArgumentError for base 1" do
30
+ ->{ 2.base(1) }.should raise_error(ArgumentError)
31
+ end
32
+
33
+ [
34
+ [3, 100, '3'], [0, 77, '0'], [20, 60, 'k'], [1234, 100, 'cy']
35
+ ].each do |n, base, r|
36
+ it "should return #{r} for #{n} in base #{base}" do
37
+ n.base(base).should == r
38
+ end
39
+ end
40
+
41
+ it "should return a Hash of bases to values when given no argument" do
42
+ 19.base.should == {
43
+ 2 => "10011", 3 => "201", 4 => "103", 5 => "34", 6 => "31",
44
+ 7 => "25", 8 => "23", 9 => "21", 10 => "19", 11 => "18",
45
+ 12 => "17", 13 => "16", 14 => "15", 15 => "14", 16 => "13",
46
+ 17 => "12", 18 => "11", 19 => "10", 20 => "j", 30 => "j",
47
+ 40 => "j", 50 => "j", 60 => "j",70 => "j", 80 => "j",
48
+ 90 => "j", 100 => "j", 1000 => "j"
49
+ }
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ describe Integer, "#positive?" do
2
+ [1, 2897, 4728, 10].each do |n|
3
+ it "returns true for positive number #{n}" do
4
+ n.should be_positive
5
+ end
6
+ end
7
+
8
+ it "returns false for 0" do
9
+ 0.should_not be_positive
10
+ end
11
+
12
+ [-1, -338, -38302, -10].each do |n|
13
+ it "returns false for negative number #{n}" do
14
+ n.should_not be_positive
15
+ end
16
+ end
17
+ end
@@ -1,25 +1,32 @@
1
1
  describe Integer, "#semiperfect?" do
2
- SEMI_PERFECT = [6,12,18,20,24,28,30,36,40,42,48,54,56,60,66,72,
3
- 78,80,84,88,90,96,100,102,104,108,112,114,120,126,
4
- 132,138,140,144,150,156,160,162,168,174,176,180,
5
- 186,192,196,198,200,204,208,210,216,220,222,224,
6
- 228,234,240,246,252,258,260,264]
7
- it "returns true if the number is semi-perfect" do
8
- SEMI_PERFECT.each do |number|
9
- number.should be_semiperfect
2
+ # A005835
3
+ @seq = [6,12,18,20,24,28,30,36,40,42,48,54,56,60,66,72,
4
+ 78,80,84,88,90,96,100,102,104,108,112,114,120,126,
5
+ 132,138,140,144,150,156,160,162,168,174,176,180,
6
+ 186,192,196,198,200,204,208,210,216,220,222,224,
7
+ 228,234,240,246,252,258,260,264].to_seq
8
+
9
+ @seq.each do |n|
10
+ it "returns true for semi-perfect number #{n}" do
11
+ n.should be_semiperfect
12
+ end
13
+
14
+ it "returns false for negative number #{-n}" do
15
+ (-n).should_not be_semiperfect
10
16
  end
11
17
  end
12
18
 
13
- it "returns true if the number is a multiple of a known semi-perfect" do
14
- (SEMI_PERFECT.combination(2).map{|_| _.reduce(:*)}.uniq - SEMI_PERFECT).
15
- shuffle.first(15).each do |number|
16
- number.should be_semiperfect
19
+ @seq.invert.sample(10).each do |n|
20
+ it "returns false for non-semi-perfect number #{n}" do
21
+ n.should_not be_semiperfect
17
22
  end
18
23
  end
19
24
 
20
25
  # Guy, R. K.
21
- # "Almost Perfect, Quasi-Perfect, Pseudoperfect, Harmonic, Weird, Multiperfect and Hyperperfect Numbers."
22
- # §B2 in Unsolved Problems in Number Theory, 2nd ed. New York: Springer-Verlag, pp. 45-53, 1994
26
+ # "Almost Perfect, Quasi-Perfect, Pseudoperfect, Harmonic, Weird,
27
+ # Multiperfect and Hyperperfect Numbers."
28
+ # §B2 in Unsolved Problems in Number Theory, 2nd ed. New York:
29
+ # Springer-Verlag, pp. 45-53, 1994
23
30
  it "returns true for 2**m * p (where m >= 1 && p.prime? && (p < 2**(m+1) && p > 2**m)" do
24
31
  [[4, 17], [4, 19], [4, 23], [4, 29], [4, 31],
25
32
  [5, 37], [5, 41], [5, 43], [5, 47], [5, 53], [5, 59], [5, 61],
@@ -29,18 +36,6 @@ describe Integer, "#semiperfect?" do
29
36
  end
30
37
  end
31
38
 
32
- it "returns false if the number is not semi-perfect" do
33
- ((1..263).to_a - SEMI_PERFECT).each do |number|
34
- number.should_not be_semiperfect
35
- end
36
- end
37
-
38
- it "returns false if the number is negative" do
39
- (1..263).each do |number|
40
- (-number).should_not be_semiperfect
41
- end
42
- end
43
-
44
39
  it "handles large input quickly and without raising a RangeError" do
45
40
  require 'timeout'
46
41
  lambda do
@@ -0,0 +1,17 @@
1
+ describe Integer, "#wieferich_prime?" do
2
+ # A001220
3
+ @seq = [1093, 3511]
4
+
5
+ @seq.each do |n|
6
+ it "should return true for Wieferich-prime #{n}" do
7
+ n.should be_wieferich_prime
8
+ end
9
+ end
10
+
11
+ @seq.to_seq.invert.sample(10).each do |n|
12
+ it "should return false for non-Wieferich-prime #{n}" do
13
+ n.should_not be_wieferich_prime
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,20 @@
1
+ describe Integer, "#woodall?" do
2
+ # A003261
3
+ @seq = [1,7,23,63,159,383,895,2047,4607,10239,22527,
4
+ 49151,106495,229375,491519,1048575,2228223,
5
+ 4718591,9961471,20971519,44040191,92274687,
6
+ 192937983,402653183,838860799,1744830463,
7
+ 3623878655,7516192767].to_seq
8
+
9
+ @seq.sample(5).each do |n|
10
+ it "should return true for Woodall number #{n}" do
11
+ n.should be_woodall
12
+ end
13
+ end
14
+
15
+ @seq.invert.sample(5).each do |n|
16
+ it "should return false for non-Woodall number #{n}" do
17
+ n.should_not be_woodall
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ describe Integer, "#zerofree?" do
2
+ @seq = {
3
+ # A052382
4
+ A052382: [1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,21,
5
+ 22,23,24,25,26,27,28,29,31,32,33,34,35,36,37,38,
6
+ 39,41,42,43,44,45,46,47,48,49,51,52,53,54,55,56,
7
+ 57,58,59,61,62,63,64,65,66,67,68,69,71,72,73,74,
8
+ 75,76,77,78,79,81,82,83,84,85,86,87,88,89,91,92,
9
+ 93,94,95,96,97,98,99,111,112,113,114],
10
+ A038618: [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,
11
+ 61,67,71,73,79,83,89,97,113,127,131,137,139,149,
12
+ 151,157,163,167,173,179,181,191,193,197,199,211,
13
+ 223,227,229,233,239,241,251,257,263,269,271,277,
14
+ 281,283,293]
15
+ }
16
+
17
+ @seq.values.flatten.uniq.each do |n|
18
+ it "should return true for zerofree number #{n}" do
19
+ n.should be_zerofree
20
+ end
21
+ end
22
+
23
+ (@seq[:A052382].to_seq.invert.to_a << 0).each do |n|
24
+ it "should return false for non-zerofree number #{n}" do
25
+ n.should_not be_zerofree
26
+ end
27
+ end
28
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: numb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.72.1
4
+ version: 0.77.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Run Paint Run Run
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-17 00:00:00 +00:00
12
+ date: 2010-01-21 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -50,6 +50,7 @@ files:
50
50
  - lib/numb/augmented_amicable.rb
51
51
  - lib/numb/automorphic.rb
52
52
  - lib/numb/balanced_prime.rb
53
+ - lib/numb/base.rb
53
54
  - lib/numb/binomial.rb
54
55
  - lib/numb/biquadratic.rb
55
56
  - lib/numb/breeder.rb
@@ -123,6 +124,7 @@ files:
123
124
  - lib/numb/perfect_power.rb
124
125
  - lib/numb/polite.rb
125
126
  - lib/numb/polydivisible.rb
127
+ - lib/numb/positive.rb
126
128
  - lib/numb/poulet.rb
127
129
  - lib/numb/powerful.rb
128
130
  - lib/numb/practical.rb
@@ -161,7 +163,10 @@ files:
161
163
  - lib/numb/untouchable.rb
162
164
  - lib/numb/vampire.rb
163
165
  - lib/numb/weird.rb
166
+ - lib/numb/wieferich.rb
167
+ - lib/numb/woodall.rb
164
168
  - lib/numb/zeisel.rb
169
+ - lib/numb/zerofree.rb
165
170
  - spec/01_spec.rb
166
171
  - spec/abundancy_spec.rb
167
172
  - spec/abundant_spec.rb
@@ -174,6 +179,7 @@ files:
174
179
  - spec/augmented_amicable_spec.rb
175
180
  - spec/automorphic_spec.rb
176
181
  - spec/balanced_prime_spec.rb
182
+ - spec/base_spec.rb
177
183
  - spec/binomial_spec.rb
178
184
  - spec/biquadratic_spec.rb
179
185
  - spec/breeder_spec.rb
@@ -247,6 +253,7 @@ files:
247
253
  - spec/polite_spec.rb
248
254
  - spec/politeness_spec.rb
249
255
  - spec/polydivisible_spec.rb
256
+ - spec/positive_spec.rb
250
257
  - spec/poulet_spec.rb
251
258
  - spec/powerful_spec.rb
252
259
  - spec/practical_spec.rb
@@ -286,7 +293,10 @@ files:
286
293
  - spec/untouchable_spec.rb
287
294
  - spec/vampire_spec.rb
288
295
  - spec/weird_spec.rb
296
+ - spec/wieferich_prime_spec.rb
297
+ - spec/woodall_spec.rb
289
298
  - spec/zeisel_spec.rb
299
+ - spec/zerofree_spec.rb
290
300
  has_rdoc: yard
291
301
  homepage: http://github.com/runpaint/numb
292
302
  licenses: []
@@ -319,6 +329,7 @@ test_files:
319
329
  - spec/01_spec.rb
320
330
  - spec/leonardo_spec.rb
321
331
  - spec/economical_spec.rb
332
+ - spec/base_spec.rb
322
333
  - spec/unitary_perfect.rb
323
334
  - spec/proth_spec.rb
324
335
  - spec/prime_signature_spec.rb
@@ -347,8 +358,10 @@ test_files:
347
358
  - spec/perfect_power_spec.rb
348
359
  - spec/factorial_spec.rb
349
360
  - spec/carmichael_spec.rb
361
+ - spec/woodall_spec.rb
350
362
  - spec/abundancy_spec.rb
351
363
  - spec/polite_spec.rb
364
+ - spec/zerofree_spec.rb
352
365
  - spec/automorphic_spec.rb
353
366
  - spec/minimal_spec.rb
354
367
  - spec/jacobsthal_lucas_spec.rb
@@ -399,6 +412,7 @@ test_files:
399
412
  - spec/amicable_spec.rb
400
413
  - spec/happy_spec.rb
401
414
  - spec/hexagonal_spec.rb
415
+ - spec/wieferich_prime_spec.rb
402
416
  - spec/fibonacci_spec.rb
403
417
  - spec/triangular_spec.rb
404
418
  - spec/integer_p_spec.rb
@@ -441,3 +455,4 @@ test_files:
441
455
  - spec/noncototient_spec.rb
442
456
  - spec/aspiring_spec.rb
443
457
  - spec/mobius_spec.rb
458
+ - spec/positive_spec.rb