numb 0.152.0 → 0.170.0
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.
- data/VERSION +1 -1
- data/lib/numb/bell.rb +9 -12
- data/lib/numb/bernoulli.rb +7 -8
- data/lib/numb/catalan.rb +1 -5
- data/lib/numb/divisors/abundant.rb +58 -0
- data/lib/numb/divisors/aliquot.rb +31 -0
- data/lib/numb/divisors/amicable.rb +38 -0
- data/lib/numb/divisors/perfect.rb +73 -0
- data/lib/numb/divisors.rb +389 -0
- data/lib/numb/entringer.rb +2 -0
- data/lib/numb/figurate.rb +138 -0
- data/lib/numb/in_sequence.rb +11 -0
- data/lib/numb/jacobsthal_lucas.rb +5 -6
- data/lib/numb/knuth.rb +1 -4
- data/lib/numb/lucas.rb +5 -5
- data/lib/numb/lucas2.rb +11 -0
- data/lib/numb/lychrel.rb +0 -4
- data/lib/numb/palindrome.rb +8 -0
- data/lib/numb/pell_lucas.rb +9 -0
- data/lib/numb/primes.rb +164 -0
- data/lib/numb/pronic.rb +1 -0
- data/lib/numb/q.rb +13 -0
- data/lib/numb/schr/303/266der.rb +20 -0
- data/lib/numb/segmented.rb +29 -0
- data/lib/numb/stirling.rb +9 -0
- data/lib/numb/stirling2.rb +9 -0
- data/lib/numb/strictly_non_palindromic.rb +1 -5
- data/lib/numb/super_catalan.rb +17 -0
- data/lib/numb/super_d.rb +6 -0
- data/lib/numb/takeuchi.rb +18 -0
- data/lib/numb/unhappy.rb +2 -0
- data/lib/numb.rb +1 -53
- data/spec/numb/first_with_n_divisors_spec.rb +15 -0
- data/spec/numb/highly_composite_spec.rb +1 -1
- data/spec/numb/jacobsthal_lucas_spec.rb +19 -11
- data/spec/numb/lucas2_spec.rb +30 -0
- data/spec/numb/lucas_spec.rb +17 -9
- data/spec/numb/minimal_spec.rb +1 -1
- data/spec/numb/near_square_spec.rb +54 -0
- data/spec/numb/octahedral_spec.rb +29 -0
- data/spec/numb/palindrome_spec.rb +43 -0
- data/spec/numb/pell_lucas_spec.rb +28 -0
- data/spec/numb/pentatope_spec.rb +15 -0
- data/spec/numb/primitive_abundant_spec.rb +21 -0
- data/spec/numb/pyramidal_spec.rb +42 -0
- data/spec/numb/q_spec.rb +31 -0
- data/spec/numb/schr/303/266der_spec.rb +28 -0
- data/spec/numb/segmented_spec.rb +29 -0
- data/spec/numb/square_part_spec.rb +15 -0
- data/spec/numb/star_spec.rb +29 -0
- data/spec/numb/stella_octangula_spec.rb +29 -0
- data/spec/numb/stirling2_spec.rb +23 -0
- data/spec/numb/stirling_spec.rb +23 -0
- data/spec/numb/super_catalan_spec.rb +29 -0
- data/spec/numb/super_d_spec.rb +68 -0
- data/spec/numb/takeuchi_spec.rb +28 -0
- data/spec/numb/tetrahedral_spec.rb +15 -0
- metadata +63 -100
- data/lib/numb/abundancy.rb +0 -8
- data/lib/numb/abundant.rb +0 -20
- data/lib/numb/achilles.rb +0 -15
- data/lib/numb/aliquot_sequence.rb +0 -13
- data/lib/numb/almost_perfect.rb +0 -8
- data/lib/numb/almost_prime.rb +0 -6
- data/lib/numb/amicable.rb +0 -6
- data/lib/numb/aspiring.rb +0 -8
- data/lib/numb/augmented_amicable.rb +0 -7
- data/lib/numb/balanced_prime.rb +0 -10
- data/lib/numb/betrothed.rb +0 -8
- data/lib/numb/breeder.rb +0 -9
- data/lib/numb/brilliant.rb +0 -7
- data/lib/numb/centered_cube.rb +0 -7
- data/lib/numb/centered_hexagonal.rb +0 -6
- data/lib/numb/centered_n_gonal.rb +0 -9
- data/lib/numb/centered_pentagonal.rb +0 -6
- data/lib/numb/centered_square.rb +0 -5
- data/lib/numb/centered_triangular.rb +0 -5
- data/lib/numb/composite.rb +0 -5
- data/lib/numb/coprime.rb +0 -9
- data/lib/numb/cube.rb +0 -5
- data/lib/numb/d.rb +0 -6
- data/lib/numb/decagonal.rb +0 -5
- data/lib/numb/deficient.rb +0 -19
- data/lib/numb/dihedral_prime.rb +0 -26
- data/lib/numb/dodecagonal.rb +0 -5
- data/lib/numb/e_divisors.rb +0 -10
- data/lib/numb/e_perfect.rb +0 -7
- data/lib/numb/economical.rb +0 -16
- data/lib/numb/emrip.rb +0 -15
- data/lib/numb/equidigital.rb +0 -18
- data/lib/numb/extravagant.rb +0 -18
- data/lib/numb/fermat_pseudoprime.rb +0 -9
- data/lib/numb/friendly.rb +0 -9
- data/lib/numb/full_reptend_prime.rb +0 -5
- data/lib/numb/giuga.rb +0 -7
- data/lib/numb/harshad.rb +0 -9
- data/lib/numb/heptagonal.rb +0 -5
- data/lib/numb/hexagonal.rb +0 -6
- data/lib/numb/highly_abundant.rb +0 -7
- data/lib/numb/highly_composite.rb +0 -12
- data/lib/numb/hoax.rb +0 -7
- data/lib/numb/hyperperfect.rb +0 -7
- data/lib/numb/impolite.rb +0 -6
- data/lib/numb/infinitary_divisors.rb +0 -15
- data/lib/numb/infinitary_perfect.rb +0 -6
- data/lib/numb/interprime.rb +0 -6
- data/lib/numb/k_perfect.rb +0 -8
- data/lib/numb/mersenne_prime.rb +0 -5
- data/lib/numb/minimal.rb +0 -8
- data/lib/numb/multiamicable.rb +0 -7
- data/lib/numb/myriagonal.rb +0 -5
- data/lib/numb/n_gonal.rb +0 -7
- data/lib/numb/next_prev_prime.rb +0 -13
- data/lib/numb/nth_prime.rb +0 -17
- data/lib/numb/number_of_divisors.rb +0 -22
- data/lib/numb/octagonal.rb +0 -5
- data/lib/numb/ore.rb +0 -8
- data/lib/numb/pentagonal.rb +0 -5
- data/lib/numb/perfect.rb +0 -8
- data/lib/numb/perfect_power.rb +0 -9
- data/lib/numb/polite.rb +0 -7
- data/lib/numb/powerful.rb +0 -10
- data/lib/numb/practical.rb +0 -26
- data/lib/numb/prime_count.rb +0 -16
- data/lib/numb/prime_signature.rb +0 -5
- data/lib/numb/primitive_pseudoperfect.rb +0 -5
- data/lib/numb/rhonda.rb +0 -6
- data/lib/numb/rough.rb +0 -5
- data/lib/numb/safe_prime.rb +0 -5
- data/lib/numb/semiperfect.rb +0 -20
- data/lib/numb/semiprime.rb +0 -6
- data/lib/numb/smith.rb +0 -7
- data/lib/numb/smooth.rb +0 -5
- data/lib/numb/sociable.rb +0 -6
- data/lib/numb/sophie_germain_prime.rb +0 -5
- data/lib/numb/square.rb +0 -7
- data/lib/numb/square_free.rb +0 -6
- data/lib/numb/square_triangular.rb +0 -5
- data/lib/numb/squared_triangular.rb +0 -5
- data/lib/numb/sublime.rb +0 -6
- data/lib/numb/sum_of_e_divisors.rb +0 -10
- data/lib/numb/sum_of_infinitary_divisors.rb +0 -9
- data/lib/numb/sum_of_unitary_divisors.rb +0 -5
- data/lib/numb/super_poulet.rb +0 -5
- data/lib/numb/superabundant.rb +0 -18
- data/lib/numb/superperfect.rb +0 -6
- data/lib/numb/triangular.rb +0 -6
- data/lib/numb/twin_prime.rb +0 -5
- data/lib/numb/unitary_amicable.rb +0 -7
- data/lib/numb/unitary_divisor.rb +0 -5
- data/lib/numb/unitary_perfect.rb +0 -7
- data/lib/numb/unitary_sociable.rb +0 -7
- data/lib/numb/untouchable.rb +0 -14
- data/lib/numb/unusual.rb +0 -5
- data/lib/numb/weird.rb +0 -8
- data/lib/numb/wieferich.rb +0 -6
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.170.0
|
data/lib/numb/bell.rb
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
class Integer
|
|
2
2
|
def bell?
|
|
3
|
-
|
|
4
|
-
r = 1
|
|
5
|
-
loop do
|
|
6
|
-
row = [triangle[r - 1][r - 1]]
|
|
7
|
-
(1..r).each do |c|
|
|
8
|
-
row << triangle[r - 1][c - 1] + row[c - 1]
|
|
9
|
-
end
|
|
10
|
-
triangle[r] = row
|
|
11
|
-
return false if row.first > self
|
|
12
|
-
return true if row.first == self
|
|
13
|
-
r += 1
|
|
14
|
-
end
|
|
3
|
+
in_sequence?(seq: :bell)
|
|
15
4
|
end
|
|
5
|
+
|
|
6
|
+
def bell
|
|
7
|
+
n = self
|
|
8
|
+
return 1 if zero?
|
|
9
|
+
(0..(n-1)).map{|k| k.bell * (n-1).choose(k)}.reduce(:+)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
memoize :bell
|
|
16
13
|
end
|
data/lib/numb/bernoulli.rb
CHANGED
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
class Integer
|
|
3
3
|
# TODO: Consider http://cims.nyu.edu/~harvey/bernmm/
|
|
4
4
|
def bernoulli
|
|
5
|
-
return
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
m.downto(1){|j| a[j - 1] = j * (a[j - 1] - a[j])}
|
|
11
|
-
end
|
|
12
|
-
a.first
|
|
5
|
+
return 1 if zero?
|
|
6
|
+
m = self
|
|
7
|
+
(m.zero? ? 1 : 0) - (0...m).map do |k|
|
|
8
|
+
m.choose(k) * Rational(k.bernoulli, m - k + 1)
|
|
9
|
+
end.reduce(:+)
|
|
13
10
|
end
|
|
11
|
+
|
|
12
|
+
memoize :bernoulli
|
|
14
13
|
end
|
data/lib/numb/catalan.rb
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
class Integer
|
|
3
|
+
# An abundant number is a number n for which σ(n) > 2n. That is, the sum of
|
|
4
|
+
# its divisors exceeds 2n. (See Integer#σ to compute the sum of the divisors
|
|
5
|
+
# of an arbitrary integer).
|
|
6
|
+
#
|
|
7
|
+
# Returns true if the number is abundant; false otherwise. Aliased to
|
|
8
|
+
# Integer#excessive?.
|
|
9
|
+
#
|
|
10
|
+
# 96.abundant? #=> true
|
|
11
|
+
# 100.abundant? #=> true
|
|
12
|
+
# 345.abundant? #=> false
|
|
13
|
+
#
|
|
14
|
+
def abundant?
|
|
15
|
+
return false unless positive?
|
|
16
|
+
σ > (2 * self)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
alias :excessive? :abundant?
|
|
20
|
+
|
|
21
|
+
def abundancy
|
|
22
|
+
Rational(σ, self)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
memoize :abundancy
|
|
26
|
+
|
|
27
|
+
def friendly?(*others)
|
|
28
|
+
raise ArgumentError unless others.size >= 1 && others.uniq.size == others.size
|
|
29
|
+
abundancy = self.abundancy
|
|
30
|
+
others.all? {|o| o.abundancy == abundancy}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def highly_abundant?
|
|
34
|
+
return true if self == 1
|
|
35
|
+
(self - 1).downto(1).all?{|m| σ > m.σ }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def primitive_abundant?
|
|
39
|
+
abundant? and proper_divisors.all?(&:deficient?)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def superabundant?
|
|
43
|
+
return true if self == 1
|
|
44
|
+
# Constraints due to "Abundant Numbers and the Riemann Hypothesis",
|
|
45
|
+
# Briggs, 2006, Experimental Mathematics, vol. 15, no. 2
|
|
46
|
+
ex = primaries.map(&:last)
|
|
47
|
+
return false unless [ex.last, ex.first] == ex.minmax
|
|
48
|
+
primaries[1..-1].all? do |b, e|
|
|
49
|
+
(e - (ex[0] * Math.log(b, primaries[0][0])).floor <= 1) and e < 2**(ex[0] + 2)
|
|
50
|
+
end or return false
|
|
51
|
+
return false unless [4, 36].include?(self) or ex.last == 1
|
|
52
|
+
1.upto(self - 1).all? do |m|
|
|
53
|
+
m.abundancy < abundancy
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
memoize :superabundant?
|
|
57
|
+
end
|
|
58
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
class Integer
|
|
3
|
+
def aliquot_sequence(max_iterations=(self > 100 ? 10 : sqrt),
|
|
4
|
+
summatory_function=->(n){ n.aliquot_sum })
|
|
5
|
+
sequence = [self]
|
|
6
|
+
max_iterations.floor.times do |limit|
|
|
7
|
+
sequence << summatory_function[sequence.last]
|
|
8
|
+
break if sequence[0..-2].include?(sequence.last)
|
|
9
|
+
return sequence << (1/0.0) if limit.consecutive?(max_iterations)
|
|
10
|
+
end
|
|
11
|
+
sequence
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def sociable?(t)
|
|
15
|
+
return false unless t >= 3
|
|
16
|
+
aliquot_sequence(t.succ).last == self
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def unitary_sociable?(t)
|
|
20
|
+
return false unless t >= 3
|
|
21
|
+
seq = aliquot_sequence(t.succ, ->(n){ n.sum_of_unitary_divisors - n})
|
|
22
|
+
seq.size - 1 == t and seq.last == self
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def aspiring?(max_iterations=10)
|
|
26
|
+
return false if perfect?
|
|
27
|
+
(last = aliquot_sequence(max_iterations).last).to_f.finite? ?
|
|
28
|
+
last.perfect? :
|
|
29
|
+
false
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
|
|
8
|
+
def amicable?(other)
|
|
9
|
+
n, m = [self, other].minmax
|
|
10
|
+
m.multiamicable?(n, 1, 1)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def augmented_amicable?(n)
|
|
14
|
+
m = self
|
|
15
|
+
[m.σ, n.σ].all?{|sigma| sigma == m + n - 1}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def betrothed?(m)
|
|
19
|
+
σ == m.σ and consecutive?(σ - m)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
alias :quasi_amicable? :betrothed?
|
|
23
|
+
alias :reduced_amicable? :betrothed?
|
|
24
|
+
|
|
25
|
+
def breeder?(b)
|
|
26
|
+
a = self
|
|
27
|
+
x = (a.σ - a).fdiv(b)
|
|
28
|
+
abx = a + (b*x)
|
|
29
|
+
(abx == a.σ) and (abx == b.σ * (x + 1))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def unitary_amicable?(n)
|
|
33
|
+
[n + self, sum_of_unitary_divisors].all? do |other|
|
|
34
|
+
other == n.sum_of_unitary_divisors
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
class Integer
|
|
3
|
+
def k_perfect?(k)
|
|
4
|
+
σ == k * self
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
alias :multiply_perfect? :k_perfect?
|
|
8
|
+
|
|
9
|
+
def perfect?
|
|
10
|
+
return false if self < 6 or self.odd? or self.to_s !~ /(6|8)$/
|
|
11
|
+
return false if self != 6 and digital_root != 1
|
|
12
|
+
k_perfect?(2)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def semiperfect?
|
|
16
|
+
return false if deficient?
|
|
17
|
+
return true if perfect?
|
|
18
|
+
possibles = { 0 => true}
|
|
19
|
+
proper_sod = (sod = σ || 0) - self
|
|
20
|
+
proper_divisors.reverse.each do |divisor|
|
|
21
|
+
possibles.keys.each do |possible|
|
|
22
|
+
possibles.delete(possible) if possible + sod < self
|
|
23
|
+
x = possible + divisor
|
|
24
|
+
return true if x == self or x == proper_sod
|
|
25
|
+
possibles[x] = true if x < self
|
|
26
|
+
end
|
|
27
|
+
sod -= divisor
|
|
28
|
+
end
|
|
29
|
+
false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
alias :pseudoperfect? :semiperfect?
|
|
33
|
+
|
|
34
|
+
def almost_perfect?
|
|
35
|
+
return true if self == 1
|
|
36
|
+
proper_divisors.reduce(:+) == self - 1
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
alias :least_deficient? :almost_perfect?
|
|
40
|
+
alias :slightly_defective? :almost_perfect?
|
|
41
|
+
|
|
42
|
+
def e_perfect?
|
|
43
|
+
return false if odd?
|
|
44
|
+
σe == 2 * self
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def unitary_perfect?
|
|
48
|
+
proper_divisors.select do |divisor|
|
|
49
|
+
unitary_divisor?(divisor)
|
|
50
|
+
end.reduce(:+) == self
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def hyperperfect?(k=1)
|
|
54
|
+
raise ArgumentError unless k >= 1
|
|
55
|
+
(1 + (k * (σ - self - 1))) == self
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def superperfect?
|
|
59
|
+
σ.σ == 2 * self
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def sublime?
|
|
63
|
+
number_of_divisors.perfect? and σ.perfect?
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def primitive_pseudoperfect?
|
|
67
|
+
pseudoperfect? and proper_divisors.sort.none?(&:pseudoperfect?)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def infinitary_perfect?
|
|
71
|
+
σ∞ == 2*self
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
class Integer
|
|
3
|
+
def weird?
|
|
4
|
+
return false unless positive?
|
|
5
|
+
return false if odd? && self < (10 ** 17)
|
|
6
|
+
not semiperfect? and abundant?
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def unusual?
|
|
10
|
+
prime_factors.max > sqrt
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def untouchable?
|
|
14
|
+
# * The first untouchable integer is 2
|
|
15
|
+
# * Perfect numbers are never untouchable because they can be expressed
|
|
16
|
+
# as the sum of their own proper divisors
|
|
17
|
+
# * If p is prime, the sum of the proper divisors of p**2 is p + 1;
|
|
18
|
+
# therefore, no untouchable number is one more than a prime.
|
|
19
|
+
return false if self < 2 or perfect? or (self - 1).prime?
|
|
20
|
+
(1..((self - 1)**2)).none? do |m|
|
|
21
|
+
m.σ - m == self
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def unitary_divisor?(x)
|
|
26
|
+
x.coprime?(self/x)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def powerful?
|
|
30
|
+
return false unless positive?
|
|
31
|
+
divisors = self.divisors
|
|
32
|
+
divisors.select {|d| d.prime? }.all?{|prime| divisors.include? (prime ** 2)}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
alias :handsome? :powerful?
|
|
36
|
+
|
|
37
|
+
# An Achilles number is powerful but not a perfect power.
|
|
38
|
+
#
|
|
39
|
+
# Returns true if self is an Achilles number; false otherwise.
|
|
40
|
+
#
|
|
41
|
+
# 1152.achilles? #=> true
|
|
42
|
+
# 4563.achilles? #=> true
|
|
43
|
+
# 100.achilles? #=> false
|
|
44
|
+
#
|
|
45
|
+
def achilles?
|
|
46
|
+
powerful? and not perfect_power?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def perfect_power?
|
|
50
|
+
return false unless positive?
|
|
51
|
+
return true if self == 1
|
|
52
|
+
divisors = self.divisors
|
|
53
|
+
(2..Math.log2(self)).any? { |pow| divisors.any? {|div| (div ** pow) == self} }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def brilliant?
|
|
57
|
+
pfacts = prime_factors
|
|
58
|
+
pfacts.size == 2 and pfacts.map{|f| f.to_s.size}.uniq.size == 1
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def coprime?(x)
|
|
62
|
+
gcd(x) == 1
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
alias :⊥ :coprime?
|
|
66
|
+
alias :stranger? :coprime?
|
|
67
|
+
|
|
68
|
+
# A deficient number is a number n for which σ(n) < 2n. That is, the sum of
|
|
69
|
+
# its divisors are less than the number. (To calculate the sum of divisors
|
|
70
|
+
# for an arbitrary integer see Integer#σ).
|
|
71
|
+
#
|
|
72
|
+
# Returns true if the number is deficient; false otherwise.
|
|
73
|
+
#
|
|
74
|
+
# 8.deficient? #=> true
|
|
75
|
+
# 27.deficient? #=> true
|
|
76
|
+
# 6.deficient? #=> false
|
|
77
|
+
#
|
|
78
|
+
def deficient?
|
|
79
|
+
return false unless positive?
|
|
80
|
+
σ < (2 * self)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
alias :defective? :deficient?
|
|
84
|
+
|
|
85
|
+
def e_divisors
|
|
86
|
+
return [1] if self == 1
|
|
87
|
+
pfacts = primaries
|
|
88
|
+
comb = pfacts.map{|p,a| (1..a).select{|b| a.divides?(b)}.map{|b| p**b}}
|
|
89
|
+
comb.flatten.permutation(pfacts.size).select do |perm|
|
|
90
|
+
perm.each_with_index.all?{|x,i| comb[i].include? x}
|
|
91
|
+
end.map{|perm| perm.reduce(:*)}
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# An extravagant number has fewer digits than the number of digits in its
|
|
95
|
+
# prime factorization (including exponents).
|
|
96
|
+
#
|
|
97
|
+
# Returns true if self is extravagant; false otherwise. Aliased to
|
|
98
|
+
# Integer#wasteful?.
|
|
99
|
+
#
|
|
100
|
+
# 234.extravagant? #=> true
|
|
101
|
+
# 87.extravagant? #=> true
|
|
102
|
+
# 81.extravagant? #=> false
|
|
103
|
+
#
|
|
104
|
+
def extravagant?
|
|
105
|
+
digits.size < prime_division.flatten.reject{|d|d==1}.join.to_i.digits.size
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
alias :wasteful? :extravagant?
|
|
109
|
+
|
|
110
|
+
def politeness
|
|
111
|
+
divisors.select{|d| d > 1}.select{|d| d.odd?}.size
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def impolite?
|
|
115
|
+
not polite?
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def polite?
|
|
119
|
+
return true if self == 1
|
|
120
|
+
politeness.positive?
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def proper_divisors
|
|
124
|
+
divisors.reject {|d| d == self }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def divisors
|
|
128
|
+
return [] unless positive?
|
|
129
|
+
return [1, self] if prime?
|
|
130
|
+
(1..isqrt).select { |n| (self % n).zero? }.
|
|
131
|
+
map {|n| [n, self/n]}.flatten.uniq
|
|
132
|
+
end
|
|
133
|
+
memoize :divisors
|
|
134
|
+
|
|
135
|
+
def sum_of_divisors
|
|
136
|
+
@sod ||= divisors.reduce(:+)
|
|
137
|
+
end
|
|
138
|
+
alias :σ :sum_of_divisors
|
|
139
|
+
|
|
140
|
+
def aliquot_sum
|
|
141
|
+
return 0 if zero?
|
|
142
|
+
σ - self
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def divides?(n)
|
|
146
|
+
not n.zero? and (self % n).zero?
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def σe
|
|
150
|
+
# TODO: If squarefree, the sum of a number’s e-divisors is the number
|
|
151
|
+
# itself. Do we gain anything significant by special-casing this?
|
|
152
|
+
e_divisors.reduce(:+)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
alias :sum_of_e_divisors :σe
|
|
156
|
+
|
|
157
|
+
def σ∞
|
|
158
|
+
infinitary_divisors.reduce :+
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
alias :sum_of_infinitary_divisors :σ∞
|
|
162
|
+
alias :isigma :σ∞
|
|
163
|
+
|
|
164
|
+
def sum_of_unitary_divisors
|
|
165
|
+
divisors.select{|d| unitary_divisor?(d)}.reduce(:+) or 0
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def highly_composite?
|
|
169
|
+
return false if self > 6 and not (abundant? or primorial_product?)
|
|
170
|
+
return true if [1,4,36].include?(self)
|
|
171
|
+
minimal? and (self - 1).downto(1).all?{|n| τ > n.τ}
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
alias :julian? :highly_composite?
|
|
175
|
+
|
|
176
|
+
def d?
|
|
177
|
+
knödel?(3)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# A number which is either frugal or equidigital.
|
|
181
|
+
#
|
|
182
|
+
# Returns true if self is economical; false otherwise.
|
|
183
|
+
#
|
|
184
|
+
# See also Integer#equidigital? and Integer#frugal?.
|
|
185
|
+
#
|
|
186
|
+
# 243.economical? #=> true
|
|
187
|
+
# 7.economical? #=> true
|
|
188
|
+
# 989.economical? #=> false
|
|
189
|
+
#
|
|
190
|
+
def economical?
|
|
191
|
+
equidigital? or frugal?
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# An equidigital number has the same number of digits as
|
|
195
|
+
# the number of digits in its prime factorization (including exponents).
|
|
196
|
+
#
|
|
197
|
+
# For example, 35 is equidigital because it has two digits and two 1-digit
|
|
198
|
+
# prime factors (5 and 7).
|
|
199
|
+
#
|
|
200
|
+
# Returns true if self is equidigital; false otherwise.
|
|
201
|
+
#
|
|
202
|
+
# 81.equidigital? #=> true
|
|
203
|
+
# 49.equidigital? #=> true
|
|
204
|
+
# 1287.equidigital? #=> false
|
|
205
|
+
#
|
|
206
|
+
def equidigital?
|
|
207
|
+
digits.size == prime_division.flatten.reject{|d|d==1}.join.to_i.digits.size
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def giuga?
|
|
211
|
+
composite? and prime_factors.uniq.all? do |p|
|
|
212
|
+
((self / p) - 1).divides?(p)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def harshad?
|
|
217
|
+
self >= 1 and (self % digital_sum).zero?
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
alias :niven? :harshad?
|
|
221
|
+
alias :multidigital? :harshad?
|
|
222
|
+
|
|
223
|
+
def hoax?
|
|
224
|
+
return false unless composite?
|
|
225
|
+
sum_of_digits == prime_factors.uniq.map{|f| f.sum_of_digits}.reduce(:+)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def infinitary_divisors
|
|
229
|
+
pf = Hash[prime_factors.uniq.map{|f| [f, 0]}]
|
|
230
|
+
bin = divisors.map do |d|
|
|
231
|
+
prime_divisors = pf.map(&:first)
|
|
232
|
+
[d, pf.merge(Hash[d.primaries]).
|
|
233
|
+
values.
|
|
234
|
+
map{|v| sprintf("%.#{to_s(2).size}b", v)}.join]
|
|
235
|
+
end
|
|
236
|
+
bin = Hash[bin]
|
|
237
|
+
target = bin[self].chars.map.with_index.to_a.select{|a,b| a == '0'}.map(&:last)
|
|
238
|
+
bin.select{|d,b| target.all?{|i| b[i] == '0'}}.keys.sort
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def ore?
|
|
242
|
+
div = divisors
|
|
243
|
+
Rational(div.size, div.map{|d| Rational(1, d)}.reduce(:+)).denominator == 1
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
alias :harmonic_divisor? :ore?
|
|
247
|
+
|
|
248
|
+
# Implementation of Stewart, B. M. (1954), "Sums of distinct divisors",
|
|
249
|
+
# American Journal of Mathematics 76: 779–785, doi:10.2307/2372651,
|
|
250
|
+
# MR0064800
|
|
251
|
+
def practical?
|
|
252
|
+
sum = 1
|
|
253
|
+
k = 2
|
|
254
|
+
n = self
|
|
255
|
+
while (n >= k)
|
|
256
|
+
s = 1
|
|
257
|
+
u = 0
|
|
258
|
+
while (n % k == 0)
|
|
259
|
+
n = n/k
|
|
260
|
+
s = s * k + 1
|
|
261
|
+
u += 1
|
|
262
|
+
end
|
|
263
|
+
unless (u == 0)
|
|
264
|
+
return false if (k > sum + 1)
|
|
265
|
+
sum *= s
|
|
266
|
+
end
|
|
267
|
+
k += (k == 2) ? 1 : 2
|
|
268
|
+
end
|
|
269
|
+
true
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def rhonda?(base=10)
|
|
273
|
+
d = base == 10 ? digits : to_s(base).split(//).map{|_| _.to_i(base)}
|
|
274
|
+
d.reduce(:*) == base * (prime_factors.reduce(:+) || 0)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def smith?
|
|
278
|
+
return false if prime?
|
|
279
|
+
digital_sum == prime_division.map{|d,e| d.digital_sum * e}.reduce(:+)
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def smooth?(b)
|
|
283
|
+
prime_factors.none?{|f| f > b}
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def rough?(k)
|
|
287
|
+
prime_factors.all?{|f| f >= k}
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def super_poulet?
|
|
291
|
+
poulet? and divisors.all?{|d| ((2**d) - 2).divides?(d)}
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
# Algorithm derived from Formulas for pi(n) and the n-th prime by Sebastian
|
|
295
|
+
# Martin Ruiz and Jonathan Sondow [arXiv:math/0210312v2 [math.NT]]
|
|
296
|
+
|
|
297
|
+
# Returns the number of divisors of self
|
|
298
|
+
def τ
|
|
299
|
+
# TODO: Consider something simpler, and perhaps faster, like
|
|
300
|
+
# primaries.map(&:last).map(&:succ).reduce(:*)
|
|
301
|
+
n = self
|
|
302
|
+
return @nod if defined?(@nod)
|
|
303
|
+
@nod = (1..isqrt).
|
|
304
|
+
map {|i| n.quo(i).to_i - (n - 1).quo(i).to_i }.
|
|
305
|
+
reduce(:+) * 2
|
|
306
|
+
@nod -= 1 if square?
|
|
307
|
+
@nod
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
alias :number_of_divisors :τ
|
|
311
|
+
alias :d :τ
|
|
312
|
+
memoize :τ
|
|
313
|
+
|
|
314
|
+
def perfect_power
|
|
315
|
+
return 1 if (n = self) <= 1
|
|
316
|
+
this = (n - 1).perfect_power.succ
|
|
317
|
+
this += 1 while (this.prime? or not this.perfect_power?)
|
|
318
|
+
this
|
|
319
|
+
end
|
|
320
|
+
memoize :perfect_power
|
|
321
|
+
|
|
322
|
+
def first_with_n_divisors
|
|
323
|
+
if zero? then 0
|
|
324
|
+
elsif self == 1 then 1
|
|
325
|
+
elsif not positive? then nil
|
|
326
|
+
else
|
|
327
|
+
pf = prime_factors
|
|
328
|
+
if pf.uniq == [2]
|
|
329
|
+
list = []
|
|
330
|
+
Prime.each do |prime|
|
|
331
|
+
break if prime > self
|
|
332
|
+
list << prime
|
|
333
|
+
exp = 1
|
|
334
|
+
loop do
|
|
335
|
+
pow2 = 2 ** exp
|
|
336
|
+
break if pow2 > self
|
|
337
|
+
prime **= pow2
|
|
338
|
+
break if prime > self
|
|
339
|
+
list << prime
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
list.sort.uniq.first(pf.size).reduce(:*)
|
|
343
|
+
else
|
|
344
|
+
limit = Prime.first(pf.size).zip(pf.reverse).map{|b,e| b**(e-1)}.reduce(:*)
|
|
345
|
+
neighbour = ->(e) { (self/e).divisors.reject{|d| d > e} }
|
|
346
|
+
x, div, exponents = self, divisors, {}
|
|
347
|
+
|
|
348
|
+
# TODO: Consider using limit's primaries as an upper limit on the
|
|
349
|
+
# exponents
|
|
350
|
+
Prime.each do |b|
|
|
351
|
+
max_exponent = Math.log(limit, b).floor
|
|
352
|
+
d = div.reject{|d| d > max_exponent}.sort.reverse - [1]
|
|
353
|
+
unless b == 2
|
|
354
|
+
prev_neighbours = exponents[exponents.keys.last].values.flatten
|
|
355
|
+
d.reject!{|e, n| not prev_neighbours.include?(e)}
|
|
356
|
+
end
|
|
357
|
+
exponents[b] = Hash[d.map{|e| [e, neighbour.(e)]}]
|
|
358
|
+
break if (x /= b) < 1
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
complete_chain = ->(b, e, goal=self, chain=nil) do
|
|
362
|
+
chain ||= {chain: [[b, e]]}
|
|
363
|
+
return chain unless exponents.key?(b) and exponents[b].key?(e)
|
|
364
|
+
exponents[b][e].map do |n|
|
|
365
|
+
this = {chain: chain[:chain].dup}
|
|
366
|
+
this[:chain].pop if this[:chain].last.first == b.next_prime
|
|
367
|
+
this[:chain] << [b.next_prime, n]
|
|
368
|
+
e * n < goal ? complete_chain[b.next_prime, n, goal/e, this] : this
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
exponents[2].keys.map do |e,|
|
|
373
|
+
complete_chain[2, e].flatten.map{|c| Hash[c[:chain]]}.
|
|
374
|
+
select{|c| c.values.reduce(:*) == self}.
|
|
375
|
+
map{|c| c.map{|b,e| b**(e-1)}.reduce(:*)}.
|
|
376
|
+
reject{|prod| prod > limit}
|
|
377
|
+
end.flatten.min or limit
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def minimal?
|
|
383
|
+
τ.first_with_n_divisors == self
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
def square_part
|
|
387
|
+
divisors.sort.reverse.each{|d| return d if d.square?}
|
|
388
|
+
end
|
|
389
|
+
end
|