numb 0.138.0 → 0.152.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/VERSION +1 -1
  2. data/lib/numb/abundancy.rb +2 -0
  3. data/lib/numb/achain.rb +99 -0
  4. data/lib/numb/almost_perfect.rb +2 -0
  5. data/lib/numb/amicable.rb +2 -4
  6. data/lib/numb/delannoy.rb +1 -0
  7. data/lib/numb/fibonacci.rb +1 -1
  8. data/lib/numb/goldbach.rb +6 -1
  9. data/lib/numb/harshad.rb +3 -2
  10. data/lib/numb/highly_composite.rb +2 -0
  11. data/lib/numb/hoax.rb +7 -0
  12. data/lib/numb/idempotent.rb +6 -0
  13. data/lib/numb/infinitary_divisors.rb +15 -0
  14. data/lib/numb/infinitary_perfect.rb +6 -0
  15. data/lib/numb/integer_p.rb +1 -1
  16. data/lib/numb/knuth.rb +15 -0
  17. data/lib/numb/lah.rb +6 -0
  18. data/lib/numb/motzkin.rb +16 -0
  19. data/lib/numb/multiamicable.rb +7 -0
  20. data/lib/numb/m/303/251nage.rb +23 -0
  21. data/lib/numb/nexus.rb +7 -0
  22. data/lib/numb/nsw.rb +16 -0
  23. data/lib/numb/pandigital.rb +6 -0
  24. data/lib/numb/persistent.rb +6 -0
  25. data/lib/numb/prime_power.rb +6 -0
  26. data/lib/numb/pronic.rb +1 -0
  27. data/lib/numb/square.rb +2 -2
  28. data/lib/numb/sum_of_infinitary_divisors.rb +9 -0
  29. data/lib/numb/superabundant.rb +12 -2
  30. data/lib/numb/vampire.rb +6 -5
  31. data/lib/numb.rb +17 -0
  32. data/spec/numb/achain_spec.rb +39 -0
  33. data/spec/numb/fibonacci_spec.rb +1 -1
  34. data/spec/numb/hoax_spec.rb +21 -0
  35. data/spec/numb/idempotent_spec.rb +59 -0
  36. data/spec/numb/infinitary_divisors_spec.rb +57 -0
  37. data/spec/numb/infinitary_perfect_spec.rb +21 -0
  38. data/spec/numb/integer_p_spec.rb +4 -4
  39. data/spec/numb/knuth_spec.rb +29 -0
  40. data/spec/numb/lah_spec.rb +61 -0
  41. data/spec/numb/motzkin_spec.rb +30 -0
  42. data/spec/numb/multiamicable_spec.rb +26 -0
  43. data/spec/numb/m/303/251nage_spec.rb +31 -0
  44. data/spec/numb/nexus_spec.rb +42 -0
  45. data/spec/numb/nsw_spec.rb +32 -0
  46. data/spec/numb/pandigital_spec.rb +29 -0
  47. data/spec/numb/persistent_spec.rb +44 -0
  48. data/spec/numb/prime_power_spec.rb +66 -0
  49. data/spec/numb/rough_spec.rb +37 -37
  50. data/spec/numb/square_spec.rb +16 -12
  51. data/spec/numb/sum_of_infinitary_divisors_spec.rb +15 -0
  52. data/spec/numb/superabundant_spec.rb +7 -7
  53. data/spec/numb/vampire_spec.rb +11 -11
  54. data/spec/spec_helper.rb +1 -1
  55. metadata +50 -2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.138.0
1
+ 0.152.0
@@ -3,4 +3,6 @@ class Integer
3
3
  def abundancy
4
4
  Rational(σ, self)
5
5
  end
6
+
7
+ memoize :abundancy
6
8
  end
@@ -0,0 +1,99 @@
1
+ # coding: utf-8
2
+ module AChain
3
+ def self.sequence(*terms)
4
+ chain, perms = ([1] + terms), {}
5
+ possible =->(term) do
6
+ return true if perms.values.include?(term)
7
+ options = chain.uniq.select{|perm| perm < term}
8
+ (options * 2).permutation(2).to_a.uniq.any? do |perm|
9
+ (perms[perm] ||= perm.reduce(:+)) == term
10
+ end
11
+ end
12
+ loop do
13
+ catch(:restart) do
14
+ (chain = chain.sort.reverse).each_with_index do |term, i|
15
+ return chain.sort.uniq if term == 1
16
+ next if possible[term]
17
+ chain << if term >= (chain[i.succ] * 3)
18
+ term.even? ? term / 2 : term - 1
19
+ else
20
+ term - chain[i.succ]
21
+ end
22
+ throw :restart
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def self.factor(n)
29
+ build_tree = ->(n) do
30
+ return if n == 1
31
+ p = n.prime_factors.first
32
+ q = n/p
33
+ q, p = p - 1, 1 if p == n
34
+ {left: q, value: n, right: p}.tap do |node|
35
+ node[:right] = build_tree[p] if p > 1
36
+ node[:left] = build_tree[q] if q > 1
37
+ end
38
+ end
39
+
40
+ current, chain = (t = build_tree[root = n]), [x = 1]
41
+
42
+ make_chain =->(node) do
43
+ [:right, :left].each do |dir|
44
+ if node[dir] == 2 then chain << x *= 2
45
+ elsif node[dir] and node[dir] != 1
46
+ x = make_chain[node[dir]]
47
+ end
48
+ node[:x] = x if dir == :right
49
+ end
50
+
51
+ if node[:value] == root and node[:right] == 1
52
+ if r = node[:right]
53
+ x += r.respond_to?(:fetch) ? r[:x] || 0 : r
54
+ end
55
+ chain << x
56
+ elsif node[:value] != root and node[:right] == 1
57
+ x += node[:x] if node.respond_to?(:fetch) and node[:x]
58
+ node.delete(:x)
59
+ chain << x
60
+ end
61
+ x
62
+ end
63
+ make_chain[t]
64
+ chain
65
+ end
66
+
67
+ def self.window_brute(n)
68
+ (1..n.to_s(2).count('1')).map {|w| window(n,w)}.min_by(&:size)
69
+ end
70
+
71
+ def self.window(n,w=3)
72
+ n = [*n.base(2).chars].map(&:to_i)
73
+ windows, zeroes = [[]], []
74
+ n.each do |bit|
75
+ if bit.zero? then zeroes << bit
76
+ elsif (zeroes.size + 1 + windows.last.size) > w
77
+ windows << zeroes.pop(zeroes.size) << [1]
78
+ else windows[-1] += zeroes.pop(zeroes.size) << 1
79
+ end
80
+ end
81
+ windows << zeroes unless zeroes.empty?
82
+ windows.map!{|w| [w, w.join.to_i(2).to_i]}
83
+
84
+ x = windows.first.last
85
+ self.sequence(*windows.map(&:last).reject(&:zero?).uniq).tap do |chain|
86
+ windows[1..-1].each do |bits, value|
87
+ bits.each {|bit| chain << x *= 2}
88
+ chain << x += value
89
+ end
90
+ end.sort.uniq
91
+ end
92
+ end
93
+
94
+ class Integer
95
+ def achain
96
+ self == 1 ? [1]
97
+ : [AChain.factor(self), AChain.window_brute(self)].min_by(&:size)
98
+ end
99
+ end
@@ -3,4 +3,6 @@ class Integer
3
3
  return true if self == 1
4
4
  proper_divisors.reduce(:+) == self - 1
5
5
  end
6
+
7
+ alias :least_deficient? :almost_perfect?
6
8
  end
data/lib/numb/amicable.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  class Integer
2
2
  def amicable?(other)
3
- return false if other == self
4
- [self, other].map do |n|
5
- n.proper_divisors.reduce(:+)
6
- end == [other, self]
3
+ n, m = [self, other].minmax
4
+ m.multiamicable?(n, 1, 1)
7
5
  end
8
6
  end
data/lib/numb/delannoy.rb CHANGED
@@ -22,4 +22,5 @@ class Integer
22
22
  return 1 if b.zero? or a.zero?
23
23
  [(a - 1).delannoy(b), a.delannoy(b - 1), (a - 1).delannoy(b - 1)].reduce(:+)
24
24
  end
25
+ memoize :delannoy
25
26
  end
@@ -3,6 +3,6 @@ class Integer
3
3
  return true if self == 1
4
4
  # Posamentier, Alfred; Lehmann, Ingmar (2007). The (Fabulous) FIBONACCI
5
5
  # Numbers. Prometheus Books. pp. 305
6
- [4, -4].map{|x| (5 * (self**2)) + x}.one? &:square?
6
+ [4, -4].map{|x| (5 * (self**2)) + x}.any? &:square?
7
7
  end
8
8
  end
data/lib/numb/goldbach.rb CHANGED
@@ -1,6 +1,11 @@
1
1
  class Integer
2
2
  def goldbach?
3
3
  return false unless even? and self > 2
4
- downto(2).any?{|n| n.prime? and (self - n).prime?}
4
+ #downto(2).any?{|n| n.prime? and (self - n).prime?}
5
+ Prime.each do |prime|
6
+ next if prime == 2
7
+ return true if (self - prime).prime?
8
+ return false if prime >= self
9
+ end
5
10
  end
6
11
  end
data/lib/numb/harshad.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  # coding: utf-8
2
2
  class Integer
3
3
  def harshad?
4
- return false unless self >= 1
5
- (self % digital_sum) == 0
4
+ self >= 1 and (self % digital_sum).zero?
6
5
  end
6
+
7
7
  alias :niven? :harshad?
8
+ alias :multidigital? :harshad?
8
9
  end
@@ -7,4 +7,6 @@ class Integer
7
7
  x.number_of_divisors >= n_divisors
8
8
  end
9
9
  end
10
+
11
+ alias :julian? :highly_composite?
10
12
  end
data/lib/numb/hoax.rb ADDED
@@ -0,0 +1,7 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def hoax?
4
+ return false unless composite?
5
+ sum_of_digits == prime_factors.uniq.map{|f| f.sum_of_digits}.reduce(:+)
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def idempotent(k)
4
+ (k.choose(self) * (self**(k - self))).to_i
5
+ end
6
+ end
@@ -0,0 +1,15 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def infinitary_divisors
4
+ pf = Hash[prime_factors.uniq.map{|f| [f, 0]}]
5
+ bin = divisors.map do |d|
6
+ prime_divisors = pf.map(&:first)
7
+ [d, pf.merge(Hash[d.primaries]).
8
+ values.
9
+ map{|v| sprintf("%.#{to_s(2).size}b", v)}.join]
10
+ end
11
+ bin = Hash[bin]
12
+ target = bin[self].chars.map.with_index.to_a.select{|a,b| a == '0'}.map(&:last)
13
+ bin.select{|d,b| target.all?{|i| b[i] == '0'}}.keys.sort
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def infinitary_perfect?
4
+ σ∞ == 2*self
5
+ end
6
+ end
@@ -6,6 +6,6 @@ end
6
6
 
7
7
  class Float
8
8
  def integer?
9
- round(10) == to_i
9
+ !!(sprintf("%f", self) =~ /\.0+$/)
10
10
  end
11
11
  end
data/lib/numb/knuth.rb ADDED
@@ -0,0 +1,15 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def knuth
4
+ return 1 if zero?
5
+ n = self - 1
6
+ 1 + [2 * (n/2).knuth, 3 * (n/3).knuth].min
7
+ end
8
+
9
+ def knuth?
10
+ downto(0) do |n|
11
+ next if (k = n.knuth) > self
12
+ return k == self ? true : false
13
+ end
14
+ end
15
+ end
data/lib/numb/lah.rb ADDED
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def lah(k)
4
+ ((self-1).choose(k-1) * Rational(factorial, k.factorial)).to_i
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def motzkin
4
+ n = self
5
+ return 1 if n <= 1
6
+ ((3 * (n - 1) * (n - 2).motzkin) + (2 * n).succ * (n - 1).motzkin) / (n + 2)
7
+ end
8
+
9
+ def motzkin?
10
+ (1..self).each do |n|
11
+ m = n.motzkin
12
+ next if m < self
13
+ return m == self ? true : false
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def multiamicable?(m, a, b)
4
+ return false unless m != self and m < self and a.positive? and b.positive?
5
+ m.σ - m == a*self and σ - self == b*m
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def ménage
4
+ return 1 if zero? # FIXME: Check this
5
+ return 0 unless self > 1
6
+ (0..self).map do |k|
7
+ Rational(2 * self, 2 * self - k) *
8
+ ((2 * self) - k).choose(k) *
9
+ (self - k).factorial *
10
+ (-1)**k
11
+ end.reduce(:+).to_i
12
+ end
13
+
14
+ def ménage?
15
+ (1..self).each do |n|
16
+ next if (m = n.ménage) < self
17
+ return m == self ? true : false
18
+ end
19
+ end
20
+
21
+ alias :menage :ménage
22
+ alias :menage? :ménage?
23
+ end
data/lib/numb/nexus.rb ADDED
@@ -0,0 +1,7 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def nexus(d)
4
+ (self + 1)**d.succ - self**d.succ
5
+ end
6
+ end
7
+
data/lib/numb/nsw.rb ADDED
@@ -0,0 +1,16 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def nsw
4
+ case self
5
+ when 0 then 1
6
+ when 1 then 7
7
+ else 6 * (self - 1).nsw - (self - 2).nsw
8
+ end
9
+ end
10
+ memoize(:nsw)
11
+
12
+ def nsw?
13
+ m = self
14
+ (rhs = (m**2).succ).divides?(2) and 2 * ((rhs/2).isqrt**2) == rhs
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def pandigital?
4
+ (0..9).all?{|d| digits.include? d}
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def persistent?(n)
4
+ (1..n).all?{|x| (x * self).pandigital?}
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def prime_power?(k=nil)
4
+ self == 1 or (primaries.size == 1 and (not k or primaries.first.last == k))
5
+ end
6
+ end
data/lib/numb/pronic.rb CHANGED
@@ -5,4 +5,5 @@ class Integer
5
5
  end
6
6
 
7
7
  alias :heteromecic? :pronic?
8
+ alias :oblong? :pronic?
8
9
  end
data/lib/numb/square.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  class Integer
3
3
  def square?
4
- return false if self < 0
5
- sqrt.integer?
4
+ return false unless zero? or (positive? and to_s(16)[-1] =~ /[0149]/)
5
+ (sq = sqrt).finite? ? sq.integer? : nil
6
6
  end
7
7
  end
@@ -0,0 +1,9 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def σ∞
4
+ infinitary_divisors.reduce :+
5
+ end
6
+
7
+ alias :sum_of_infinitary_divisors :σ∞
8
+ alias :isigma :σ∞
9
+ end
@@ -2,7 +2,17 @@
2
2
  class Integer
3
3
  def superabundant?
4
4
  return true if self == 1
5
- sod_over_self = Rational(σ, self)
6
- (self - 1).downto(1).all?{|m| Rational(m.σ, m) < sod_over_self}
5
+ # Constraints due to "Abundant Numbers and the Riemann Hypothesis",
6
+ # Briggs, 2006, Experimental Mathematics, vol. 15, no. 2
7
+ ex = primaries.map(&:last)
8
+ return false unless [ex.last, ex.first] == ex.minmax
9
+ primaries[1..-1].all? do |b, e|
10
+ (e - (ex[0] * Math.log(b, primaries[0][0])).floor <= 1) and e < 2**(ex[0] + 2)
11
+ end or return false
12
+ return false unless [4, 36].include?(self) or ex.last == 1
13
+ 1.upto(self - 1).all? do |m|
14
+ m.abundancy < abundancy
15
+ end
7
16
  end
17
+ memoize :superabundant?
8
18
  end
data/lib/numb/vampire.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  # coding: utf-8
2
2
  class Integer
3
3
  def vampire?
4
- return false unless !prime? and digits.size.even?
5
- digits.permutation.map do |perm|
6
- [:first,:last].map {|pos| perm.send(pos,(digits.size/2)).join.to_i }.sort
7
- end.uniq.any? do |fangs|
8
- fangs.reduce(:*) == self
4
+ return false unless composite? and digits.size.even?
5
+ seen = {}
6
+ digits.permutation.any? do |perm|
7
+ fangs = [:first,:last].map {|pos| perm.send(pos,(digits.size/2)).join.to_i }.sort
8
+ next if seen.key?(fangs)
9
+ seen[fangs] = fangs.reduce(:*) == self
9
10
  end
10
11
  end
11
12
  end
data/lib/numb.rb CHANGED
@@ -1,5 +1,21 @@
1
1
  # coding: utf-8
2
+ module Memoize
3
+ def memoize(sym)
4
+ aka = "_#{sym}".to_sym
5
+ alias_method aka, sym
6
+ @@NUMB ||= {}
7
+ Integer.send(:define_method, sym) do |*args|
8
+ @@NUMB[[self, sym, args]] ||= send(aka, *args)
9
+ end
10
+ end
11
+ end
2
12
 
13
+ [Integer, Bignum].each do |klass|
14
+ class << klass
15
+ include Memoize
16
+ end
17
+ end
18
+
3
19
  class Integer
4
20
  def number_of_distinct_prime_factors
5
21
  prime_factors.uniq.size
@@ -40,6 +56,7 @@ class Integer
40
56
  (1..isqrt).select { |n| (self % n).zero? }.
41
57
  map {|n| [n, self/n]}.flatten.uniq
42
58
  end
59
+ memoize :divisors
43
60
 
44
61
  def sum_of_divisors
45
62
  @sod ||= divisors.reduce(:+)
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+ describe Integer, "#achain" do
3
+ # A003313
4
+ @seq = [0,1,2,2,3,3,4,3,4,4,5,4,5,5,5,4,5,5,6,5,6,6,6,5,6,6,6,6,7,6,7,5,6,
5
+ 6,7,6,7,7,7,6,7,7,7,7,7,7,8,6,7,7,7,7,8,7,8,7,8,8,8,7,8,8,8,6,7,7,
6
+ 8,7,8,8,9,7,8,8,8,8,8,8,9,7,8,8,8,8,8,8,9,8,9,8,9,8,9,9,9,7,8,8,8,8,]
7
+
8
+ @seq.to_enum.with_index(1) do |len, n|
9
+ achain = n.achain
10
+
11
+ it "returns an addition chain of #{len} terms for #{n}" do
12
+ (achain.size - 1).should == len
13
+ end
14
+
15
+ it "returns an addition chain for #{n} that ends with #{n}" do
16
+ achain.last.should == n
17
+ end
18
+
19
+ it "returns an addition chain for #{n} that begins with 1" do
20
+ achain.first.should == 1
21
+ end
22
+
23
+ it "returns an addition chain for #{n} without any duplicate terms" do
24
+ achain.uniq.should == achain
25
+ end
26
+
27
+ it "returns an addition chain for #{n} with terms ordered by smallest to largest" do
28
+ achain.sort.should == achain
29
+ end
30
+
31
+ it "returns an addition chain for #{n} whose terms are the sum of two preceeding terms" do
32
+ chain = achain.reverse
33
+ sums = (chain * 2).permutation(2).to_a.uniq.map{|perm| perm.reduce(:+)}
34
+ chain[0..-2].each do |t|
35
+ sums.should include(t)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -12,7 +12,7 @@ describe Integer, "#fibonacci?" do
12
12
  end
13
13
  end
14
14
 
15
- @seq.invert.sample(10).each do |n|
15
+ @seq.invert.sample(100).each do |n|
16
16
  it "returns false for non-Fibonacci number #{n}" do
17
17
  n.should_not be_fibonacci
18
18
  end
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ describe Integer, "#hoax?" do
3
+ # A019506
4
+ @seq = [22,58,84,85,94,136,160,166,202,234,250,265,274,
5
+ 308,319,336,346,355,361,364,382,391,424,438,454,
6
+ 456,476,483,516,517,526,535,562,627,634,644,645,
7
+ 650,654,660,663,690,702,706,732,735,762,778,855,
8
+ 860]
9
+
10
+ @seq.each do |n|
11
+ it "returns true for hoax number #{n}" do
12
+ n.should be_hoax
13
+ end
14
+ end
15
+
16
+ @seq.to_seq.invert.each do |n|
17
+ it "returns false for non-hoax number #{n}" do
18
+ n.should_not be_hoax
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,59 @@
1
+ # coding: utf-8
2
+ describe Integer, "#idempotent" do
3
+
4
+ @seq = {
5
+ # A000027
6
+ 1 => [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
7
+ 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,
8
+ 36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
9
+ 52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,
10
+ 68,69,70,71,72,73,74,75,76,77],
11
+ # A001788
12
+ 2 => [0,1,6,24,80,240,672,1792,4608,11520,28160,67584,
13
+ 159744,372736,860160,1966080,4456448,10027008,
14
+ 22413312,49807360,110100480,242221056,530579456,
15
+ 1157627904,2516582400,5452595200,11777605632].reject(&:zero?),
16
+ # A036216
17
+ 3 => [1,12,90,540,2835,13608,61236,262440,1082565,
18
+ 4330260,16888014,64481508,241805655,892820880,
19
+ 3252418920,11708708112,41712272649,147219785820,
20
+ 515269250370,1789882659180,6175095174171,
21
+ 21171754882872],
22
+ # A040075
23
+ 4 => [1,20,240,2240,17920,129024,860160,5406720,
24
+ 32440320,187432960,1049624576,5725224960,
25
+ 30534533120,159719096320,821412495360,
26
+ 4161823309824,20809116549120,102821517066240,
27
+ 502682972323840],
28
+ # A050982
29
+ 5 => [1,30,525,7000,78750,787500,7218750,61875000,
30
+ 502734375,3910156250,29326171875,213281250000,
31
+ 1510742187500,10458984375000,70971679687500,
32
+ 473144531250000,3105010986328125,
33
+ 20091247558593750],
34
+ # A050988
35
+ 6 => [1,42,1008,18144,272160,3592512,43110144,
36
+ 480370176,5043886848,50438868480,484213137408,
37
+ 4489976365056,40409787285504,354362750042112,
38
+ 3037395000360960,25514118003032064],
39
+ # A050989
40
+ 7 => [1,56,1764,41160,792330,13311144,201885684,
41
+ 2826399576,37096494435,461645264080,5493578642552,
42
+ 62926446269232,697434779483988,7510836086750640,
43
+ 78863778910881720,809668130151718992],
44
+ }
45
+
46
+ @seq.each do |n, values|
47
+ (1...n).each do |k|
48
+ it "returns 0 when n=#{n} and k=#{k}" do
49
+ n.idempotent(k).should be_zero
50
+ end
51
+ end
52
+
53
+ values.to_enum.with_index(n).each do |idem, k|
54
+ it "returns #{idem} for n=#{n} and k=#{k}" do
55
+ n.idempotent(k).should == idem
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,57 @@
1
+ # coding: utf-8
2
+ describe Integer, "#infinitary_divisors" do
3
+ # A077609
4
+ @seq = [
5
+ [1],
6
+ [1,2],
7
+ [1,3],
8
+ [1,4],
9
+ [1,5],
10
+ [1,2,3,6],
11
+ [1,7],
12
+ [1,2,4,8],
13
+ [1,9],
14
+ [1,2,5,10],
15
+ [1,11],
16
+ [1,3,4,12],
17
+ [1,13],
18
+ [1,2,7,14],
19
+ [1,3,5,15],
20
+ [1,16],
21
+ [1,17],
22
+ [1,2,9,18],
23
+ [1,19],
24
+ [1,4,5,20],
25
+ [1,3,7,21],
26
+ [1,2,11,22],
27
+ [1,23],
28
+ [1,2,3,4,6,8,12,24],
29
+ [1,25],
30
+ [1,2,13,26],
31
+ [1,3,9,27],
32
+ [1,4,7,28],
33
+ [1,29],
34
+ #[1]
35
+ ]
36
+
37
+ @seq.each do |id|
38
+ id.sort!
39
+ n = id.last
40
+ it "returns #{id} for #{n}" do
41
+ n.infinitary_divisors.should == id
42
+ end
43
+ end
44
+
45
+ # A037445
46
+ @counts = [1,2,2,2,2,4,2,4,2,4,2,4,2,4,4,2,2,4,2,4,4,4,2,8,
47
+ 2,4,4,4,2,8,2,4,4,4,4,4,2,4,4,8,2,8,2,4,4,4,2,4,2,
48
+ 4,4,4,2,8,4,8,4,4,2,8,2,4,4,4,4,8,2,4,4,8,2,8,2,4,
49
+ 4,4,4,8,2,4,2,4,2,8,4,4,4,8,2,8,4,4,4,4,4,8,2,4,4,
50
+ 4,2,8,2,8,8]
51
+
52
+ @counts.to_enum.with_index(1).each do |c, n|
53
+ it "returns #{c} infinitary divisors for #{n}" do
54
+ n.infinitary_divisors.uniq.count.should == c
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ describe Integer, "#infinitary_perfect?" do
3
+ # A007357
4
+ @seq = [6,60,90,36720,12646368,22276800,126463680,
5
+ 4201148160,28770487200,287704872000,1446875426304,
6
+ 2548696550400,14468754263040,590325173932032,
7
+ 3291641594841600,8854877608980480,
8
+ 32916415948416000].first(7)
9
+
10
+ @seq.each do |n|
11
+ it "returns true for infinitary perfect number #{n}" do
12
+ n.should be_infinitary_perfect
13
+ end
14
+ end
15
+
16
+ @seq.to_seq.invert.sample(7).each do |n|
17
+ it "returns false for non-infinitary perfect number #{n}" do
18
+ n.should_not be_infinitary_perfect
19
+ end
20
+ end
21
+ end