numb 0.138.0 → 0.152.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/numb/abundancy.rb +2 -0
- data/lib/numb/achain.rb +99 -0
- data/lib/numb/almost_perfect.rb +2 -0
- data/lib/numb/amicable.rb +2 -4
- data/lib/numb/delannoy.rb +1 -0
- data/lib/numb/fibonacci.rb +1 -1
- data/lib/numb/goldbach.rb +6 -1
- data/lib/numb/harshad.rb +3 -2
- data/lib/numb/highly_composite.rb +2 -0
- data/lib/numb/hoax.rb +7 -0
- data/lib/numb/idempotent.rb +6 -0
- data/lib/numb/infinitary_divisors.rb +15 -0
- data/lib/numb/infinitary_perfect.rb +6 -0
- data/lib/numb/integer_p.rb +1 -1
- data/lib/numb/knuth.rb +15 -0
- data/lib/numb/lah.rb +6 -0
- data/lib/numb/motzkin.rb +16 -0
- data/lib/numb/multiamicable.rb +7 -0
- data/lib/numb/m/303/251nage.rb +23 -0
- data/lib/numb/nexus.rb +7 -0
- data/lib/numb/nsw.rb +16 -0
- data/lib/numb/pandigital.rb +6 -0
- data/lib/numb/persistent.rb +6 -0
- data/lib/numb/prime_power.rb +6 -0
- data/lib/numb/pronic.rb +1 -0
- data/lib/numb/square.rb +2 -2
- data/lib/numb/sum_of_infinitary_divisors.rb +9 -0
- data/lib/numb/superabundant.rb +12 -2
- data/lib/numb/vampire.rb +6 -5
- data/lib/numb.rb +17 -0
- data/spec/numb/achain_spec.rb +39 -0
- data/spec/numb/fibonacci_spec.rb +1 -1
- data/spec/numb/hoax_spec.rb +21 -0
- data/spec/numb/idempotent_spec.rb +59 -0
- data/spec/numb/infinitary_divisors_spec.rb +57 -0
- data/spec/numb/infinitary_perfect_spec.rb +21 -0
- data/spec/numb/integer_p_spec.rb +4 -4
- data/spec/numb/knuth_spec.rb +29 -0
- data/spec/numb/lah_spec.rb +61 -0
- data/spec/numb/motzkin_spec.rb +30 -0
- data/spec/numb/multiamicable_spec.rb +26 -0
- data/spec/numb/m/303/251nage_spec.rb +31 -0
- data/spec/numb/nexus_spec.rb +42 -0
- data/spec/numb/nsw_spec.rb +32 -0
- data/spec/numb/pandigital_spec.rb +29 -0
- data/spec/numb/persistent_spec.rb +44 -0
- data/spec/numb/prime_power_spec.rb +66 -0
- data/spec/numb/rough_spec.rb +37 -37
- data/spec/numb/square_spec.rb +16 -12
- data/spec/numb/sum_of_infinitary_divisors_spec.rb +15 -0
- data/spec/numb/superabundant_spec.rb +7 -7
- data/spec/numb/vampire_spec.rb +11 -11
- data/spec/spec_helper.rb +1 -1
- metadata +50 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.152.0
|
data/lib/numb/abundancy.rb
CHANGED
data/lib/numb/achain.rb
ADDED
@@ -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
|
data/lib/numb/almost_perfect.rb
CHANGED
data/lib/numb/amicable.rb
CHANGED
data/lib/numb/delannoy.rb
CHANGED
data/lib/numb/fibonacci.rb
CHANGED
@@ -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}.
|
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
data/lib/numb/hoax.rb
ADDED
@@ -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
|
data/lib/numb/integer_p.rb
CHANGED
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
data/lib/numb/motzkin.rb
ADDED
@@ -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,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
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
|
data/lib/numb/pronic.rb
CHANGED
data/lib/numb/square.rb
CHANGED
data/lib/numb/superabundant.rb
CHANGED
@@ -2,7 +2,17 @@
|
|
2
2
|
class Integer
|
3
3
|
def superabundant?
|
4
4
|
return true if self == 1
|
5
|
-
|
6
|
-
|
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
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
data/spec/numb/fibonacci_spec.rb
CHANGED
@@ -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
|