numb 0.185.0 → 0.186.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/divisors/perfect.rb +3 -0
- data/lib/numb/totient.rb +34 -0
- data/spec/numb/perfect_totient_spec.rb +30 -0
- metadata +4 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.186.0
|
@@ -33,6 +33,9 @@ class Integer
|
|
33
33
|
|
34
34
|
def almost_perfect?
|
35
35
|
return true if self == 1
|
36
|
+
# TODO: All known almost perfect numbers are powers of 2. If self
|
37
|
+
# is within the range of integers thus tested, a power_of?(2) test
|
38
|
+
# would avoid the need to factorise.
|
36
39
|
proper_divisors.reduce(:+) == self - 1
|
37
40
|
end
|
38
41
|
|
data/lib/numb/totient.rb
CHANGED
@@ -7,4 +7,38 @@ class Integer
|
|
7
7
|
end
|
8
8
|
|
9
9
|
alias :totient :φ
|
10
|
+
|
11
|
+
|
12
|
+
# Returns `true` if `self` is equal to the sum of its iterated
|
13
|
+
# totients, otherwise `false`
|
14
|
+
#
|
15
|
+
# For example: φ(183) = 120
|
16
|
+
# φ(120) = 32
|
17
|
+
# φ(32) = 16
|
18
|
+
# φ(16) = 8
|
19
|
+
# φ(4) = 2
|
20
|
+
# φ(2) = 1
|
21
|
+
# 120 + 32 + 16 + 8 + 4 + 2 + 1 = 183
|
22
|
+
# @return [true, false] `true` if `self` is a perfect totient; `false` otherwise.
|
23
|
+
def perfect_totient?
|
24
|
+
# TODO: Possible optimisation: once the totient is a power of 2,
|
25
|
+
# which we identify using bit ops, it is predictable what totients
|
26
|
+
# will follow. For example, consider 441027. Its iterated totients
|
27
|
+
# are [294012, 97992, 32640, 8192, 4096, 2048, 1024, 512, 256,
|
28
|
+
# 128, 64, 32, 16, 8, 4, 2, 1], i.e. 17 iterations are
|
29
|
+
# needed. Once we hit 8192, we can derive [2, 4, 8, 16, 32, 64,
|
30
|
+
# 128, 256, 512, 1024, 2048, 4096, 8192], add the 1, then return.
|
31
|
+
|
32
|
+
# TODO: The more obvious tweak is to return true immediately when
|
33
|
+
# self is a power of 3. I want to write a #power_of? predicate for
|
34
|
+
# the general case first, then benchmark it for use here.
|
35
|
+
return false if even?
|
36
|
+
a = [totient]
|
37
|
+
sum = a.first
|
38
|
+
until a.last == 1 or sum > self
|
39
|
+
a << a.last.totient
|
40
|
+
sum += a.last
|
41
|
+
end
|
42
|
+
sum == self
|
43
|
+
end
|
10
44
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
describe Integer, "#perfect_totient?" do
|
2
|
+
# A082897
|
3
|
+
@seq = [3,9,15,27,39,81,111,183,243,255,327,363,471,729,
|
4
|
+
2187,2199,3063,4359,4375,5571,6561,8751,15723,
|
5
|
+
19683,36759,46791,59049,65535,140103,177147,
|
6
|
+
208191,441027,531441,1594323,4190263,4782969,
|
7
|
+
9056583,14348907,43046721] |
|
8
|
+
# A091847
|
9
|
+
[15,39,111,183,255,327,363,471,2199,3063,4359,
|
10
|
+
4375,5571,8751,15723,36759,46791,65535,140103,
|
11
|
+
208191,441027,4190263,9056583,57395631,172186887,
|
12
|
+
236923383,918330183,3932935775,4294967295,
|
13
|
+
4764161215]
|
14
|
+
|
15
|
+
@seq.each do |n|
|
16
|
+
it "returns true for perfect totient number #{n}" do
|
17
|
+
n.should be_perfect_totient
|
18
|
+
end
|
19
|
+
|
20
|
+
m = n + 2
|
21
|
+
it "returns false for non-perfect-totient number #{m}" do
|
22
|
+
m.should_not be_perfect_totient
|
23
|
+
end
|
24
|
+
|
25
|
+
m += 1
|
26
|
+
it "returns false for even number #{m}" do
|
27
|
+
m.should_not be_perfect_totient
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 186
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.186.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Run Paint Run Run
|
@@ -343,6 +343,7 @@ files:
|
|
343
343
|
- spec/numb/pentatope_spec.rb
|
344
344
|
- spec/numb/perfect_power_spec.rb
|
345
345
|
- spec/numb/perfect_spec.rb
|
346
|
+
- spec/numb/perfect_totient_spec.rb
|
346
347
|
- spec/numb/perrin_spec.rb
|
347
348
|
- spec/numb/persistent_spec.rb
|
348
349
|
- spec/numb/polite_spec.rb
|
@@ -493,6 +494,7 @@ test_files:
|
|
493
494
|
- spec/numb/emrip_spec.rb
|
494
495
|
- spec/numb/minimal_spec.rb
|
495
496
|
- spec/numb/weird_spec.rb
|
497
|
+
- spec/numb/perfect_totient_spec.rb
|
496
498
|
- spec/numb/practical_spec.rb
|
497
499
|
- spec/numb/ore_spec.rb
|
498
500
|
- spec/numb/base_spec.rb
|