numb 0.185.0 → 0.186.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 CHANGED
@@ -1 +1 @@
1
- 0.185.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
- - 185
7
+ - 186
8
8
  - 0
9
- version: 0.185.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