numb 0.152.0 → 0.170.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/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
|