numb 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +10 -0
  5. data/Rakefile +52 -0
  6. data/VERSION +1 -0
  7. data/lib/numb/abundant.rb +20 -0
  8. data/lib/numb/achilles.rb +15 -0
  9. data/lib/numb/automorphic.rb +24 -0
  10. data/lib/numb/carol.rb +21 -0
  11. data/lib/numb/deficient.rb +19 -0
  12. data/lib/numb/dihedral_prime.rb +25 -0
  13. data/lib/numb/dudeney.rb +15 -0
  14. data/lib/numb/economical.rb +16 -0
  15. data/lib/numb/emrip.rb +17 -0
  16. data/lib/numb/equidigital.rb +18 -0
  17. data/lib/numb/extravagant.rb +18 -0
  18. data/lib/numb/factorion.rb +15 -0
  19. data/lib/numb/frugal.rb +16 -0
  20. data/lib/numb/happy.rb +15 -0
  21. data/lib/numb/harshad.rb +8 -0
  22. data/lib/numb/hilbert.rb +7 -0
  23. data/lib/numb/hyperperfect.rb +7 -0
  24. data/lib/numb/impolite.rb +6 -0
  25. data/lib/numb/kaprekar.rb +14 -0
  26. data/lib/numb/keith.rb +15 -0
  27. data/lib/numb/kynea.rb +9 -0
  28. data/lib/numb/mms_pair.rb +11 -0
  29. data/lib/numb/mobius.rb +11 -0
  30. data/lib/numb/narcissistic.rb +8 -0
  31. data/lib/numb/nivenmorphic.rb +9 -0
  32. data/lib/numb/ordinal.rb +11 -0
  33. data/lib/numb/parasitic.rb +10 -0
  34. data/lib/numb/perfect.rb +10 -0
  35. data/lib/numb/perfect_power.rb +9 -0
  36. data/lib/numb/polite.rb +7 -0
  37. data/lib/numb/polydivisible.rb +10 -0
  38. data/lib/numb/powerful.rb +8 -0
  39. data/lib/numb/practical.rb +26 -0
  40. data/lib/numb/prime.rb +495 -0
  41. data/lib/numb/ruby1.8.rb +9 -0
  42. data/lib/numb/ruby1.9.rb +8 -0
  43. data/lib/numb/self.rb +13 -0
  44. data/lib/numb/self_descriptive.rb +9 -0
  45. data/lib/numb/semi_perfect.rb +15 -0
  46. data/lib/numb/semiprime.rb +6 -0
  47. data/lib/numb/smarandache_wellin.rb +11 -0
  48. data/lib/numb/smith.rb +7 -0
  49. data/lib/numb/sphenic.rb +8 -0
  50. data/lib/numb/square.rb +8 -0
  51. data/lib/numb/square_free.rb +6 -0
  52. data/lib/numb/triangular.rb +8 -0
  53. data/lib/numb/trimorphic.rb +6 -0
  54. data/lib/numb/undulating.rb +11 -0
  55. data/lib/numb/vampire.rb +11 -0
  56. data/lib/numb/weird.rb +8 -0
  57. data/lib/numb.rb +80 -0
  58. data/numb.gemspec +201 -0
  59. data/spec/abundant_spec.rb +24 -0
  60. data/spec/achilles_spec.rb +24 -0
  61. data/spec/automorphic_spec.rb +208 -0
  62. data/spec/carol_spec.rb +18 -0
  63. data/spec/deficient_spec.rb +23 -0
  64. data/spec/digital_sum_spec.rb +8 -0
  65. data/spec/dihedral_prime_spec.rb +38 -0
  66. data/spec/dudeney_spec.rb +14 -0
  67. data/spec/economical_spec.rb +28 -0
  68. data/spec/emrip_spec.rb +26 -0
  69. data/spec/equidigital_spec.rb +27 -0
  70. data/spec/extravagant_spec.rb +20 -0
  71. data/spec/factor_spec.rb +22 -0
  72. data/spec/factorion_spec.rb +13 -0
  73. data/spec/frugal_spec.rb +20 -0
  74. data/spec/happy_spec.rb +24 -0
  75. data/spec/harshad_spec.rb +25 -0
  76. data/spec/hilbert_spec.rb +24 -0
  77. data/spec/hyperperfect_spec.rb +59 -0
  78. data/spec/kaprekar_spec.rb +25 -0
  79. data/spec/keith_spec.rb +21 -0
  80. data/spec/kynea_spec.rb +19 -0
  81. data/spec/maris_mcgwire_sosa_pair_spec.rb +20 -0
  82. data/spec/mobius_spec.rb +52 -0
  83. data/spec/narcissistic_spec.rb +18 -0
  84. data/spec/nivenmorphic_spec.rb +24 -0
  85. data/spec/number_of_distinct_prime_factors_spec.rb +35 -0
  86. data/spec/number_of_prime_factors_spec.rb +32 -0
  87. data/spec/ordinal_spec.rb +64 -0
  88. data/spec/parasitic_spec.rb +29 -0
  89. data/spec/perfect_power_spec.rb +24 -0
  90. data/spec/perfect_spec.rb +103 -0
  91. data/spec/polite_spec.rb +14 -0
  92. data/spec/politeness_spec.rb +11 -0
  93. data/spec/polydivisible_spec.rb +19 -0
  94. data/spec/powerful_spec.rb +25 -0
  95. data/spec/practical_spec.rb +30 -0
  96. data/spec/self_descriptive_spec.rb +19 -0
  97. data/spec/self_spec.rb +20 -0
  98. data/spec/semi_perfect_spec.rb +24 -0
  99. data/spec/semiprime_spec.rb +21 -0
  100. data/spec/smarandache_wellin_spec.rb +26 -0
  101. data/spec/smith_spec.rb +19 -0
  102. data/spec/spec_helper.rb +9 -0
  103. data/spec/sphenic_spec.rb +20 -0
  104. data/spec/square_free_spec.rb +19 -0
  105. data/spec/square_spec.rb +24 -0
  106. data/spec/triangular_spec.rb +19 -0
  107. data/spec/trimorphic_spec.rb +25 -0
  108. data/spec/undulating_spec.rb +20 -0
  109. data/spec/vampire_spec.rb +19 -0
  110. data/spec/weird_spec.rb +24 -0
  111. metadata +216 -0
data/lib/numb/prime.rb ADDED
@@ -0,0 +1,495 @@
1
+ # Extracted from 1.9's stdlib for 1.8 compatibility
2
+ # = prime.rb
3
+ #
4
+ # Prime numbers and factorization library.
5
+ #
6
+ # Copyright::
7
+ # Copyright (c) 1998-2008 Keiju ISHITSUKA(SHL Japan Inc.)
8
+ # Copyright (c) 2008 Yuki Sonoda (Yugui) <yugui@yugui.jp>
9
+ #
10
+ # Documentation::
11
+ # Yuki Sonoda
12
+ #
13
+
14
+ require "singleton"
15
+ require "forwardable"
16
+
17
+ class Integer
18
+ # Re-composes a prime factorization and returns the product.
19
+ #
20
+ # See Prime#int_from_prime_division for more details.
21
+ def Integer.from_prime_division(pd)
22
+ Prime.int_from_prime_division(pd)
23
+ end
24
+
25
+ # Returns the factorization of +self+.
26
+ #
27
+ # See Prime#prime_division for more details.
28
+ def prime_division(generator = Prime::Generator23.new)
29
+ Prime.prime_division(self, generator)
30
+ end
31
+
32
+ # Returns true if +self+ is a prime number, false for a composite.
33
+ def prime?
34
+ Prime.prime?(self)
35
+ end
36
+
37
+ # Iterates the given block over all prime numbers.
38
+ #
39
+ # See +Prime+#each for more details.
40
+ def Integer.each_prime(ubound, &block) # :yields: prime
41
+ Prime.each(ubound, &block)
42
+ end
43
+ end
44
+
45
+ #
46
+ # The set of all prime numbers.
47
+ #
48
+ # == Example
49
+ # Prime.each(100) do |prime|
50
+ # p prime #=> 2, 3, 5, 7, 11, ...., 97
51
+ # end
52
+ #
53
+ # == Retrieving the instance
54
+ # +Prime+.new is obsolete. Now +Prime+ has the default instance and you can
55
+ # access it as +Prime+.instance.
56
+ #
57
+ # For convenience, each instance method of +Prime+.instance can be accessed
58
+ # as a class method of +Prime+.
59
+ #
60
+ # e.g.
61
+ # Prime.instance.prime?(2) #=> true
62
+ # Prime.prime?(2) #=> true
63
+ #
64
+ # == Generators
65
+ # A "generator" provides an implementation of enumerating pseudo-prime
66
+ # numbers and it remembers the position of enumeration and upper bound.
67
+ # Futhermore, it is a external iterator of prime enumeration which is
68
+ # compatible to an Enumerator.
69
+ #
70
+ # +Prime+::+PseudoPrimeGenerator+ is the base class for generators.
71
+ # There are few implementations of generator.
72
+ #
73
+ # [+Prime+::+EratosthenesGenerator+]
74
+ # Uses eratosthenes's sieve.
75
+ # [+Prime+::+TrialDivisionGenerator+]
76
+ # Uses the trial division method.
77
+ # [+Prime+::+Generator23+]
78
+ # Generates all positive integers which is not divided by 2 nor 3.
79
+ # This sequence is very bad as a pseudo-prime sequence. But this
80
+ # is faster and uses much less memory than other generators. So,
81
+ # it is suitable for factorizing an integer which is not large but
82
+ # has many prime factors. e.g. for Prime#prime? .
83
+ class Prime
84
+ include Enumerable
85
+ @the_instance = Prime.new
86
+
87
+ # obsolete. Use +Prime+::+instance+ or class methods of +Prime+.
88
+ def initialize
89
+ @generator = EratosthenesGenerator.new
90
+ extend OldCompatibility
91
+ warn "Prime::new is obsolete. use Prime::instance or class methods of Prime."
92
+ end
93
+
94
+ class << self
95
+ extend Forwardable
96
+ include Enumerable
97
+ # Returns the default instance of Prime.
98
+ def instance; @the_instance end
99
+
100
+ def method_added(method) # :nodoc:
101
+ (class<< self;self;end).def_delegator :instance, method
102
+ end
103
+ end
104
+
105
+ # Iterates the given block over all prime numbers.
106
+ #
107
+ # == Parameters
108
+ # +ubound+::
109
+ # Optional. An arbitrary positive number.
110
+ # The upper bound of enumeration. The method enumerates
111
+ # prime numbers infinitely if +ubound+ is nil.
112
+ # +generator+::
113
+ # Optional. An implementation of pseudo-prime generator.
114
+ #
115
+ # == Return value
116
+ # An evaluated value of the given block at the last time.
117
+ # Or an enumerator which is compatible to an +Enumerator+
118
+ # if no block given.
119
+ #
120
+ # == Description
121
+ # Calls +block+ once for each prime number, passing the prime as
122
+ # a parameter.
123
+ #
124
+ # +ubound+::
125
+ # Upper bound of prime numbers. The iterator stops after
126
+ # yields all prime numbers p <= +ubound+.
127
+ #
128
+ # == Note
129
+ # +Prime+.+new+ returns a object extended by +Prime+::+OldCompatibility+
130
+ # in order to compatibility to Ruby 1.8, and +Prime+#each is overwritten
131
+ # by +Prime+::+OldCompatibility+#+each+.
132
+ #
133
+ # +Prime+.+new+ is now obsolete. Use +Prime+.+instance+.+each+ or simply
134
+ # +Prime+.+each+.
135
+ def each(ubound = nil, generator = EratosthenesGenerator.new, &block)
136
+ generator.upper_bound = ubound
137
+ generator.each(&block)
138
+ end
139
+
140
+
141
+ # Returns true if +value+ is prime, false for a composite.
142
+ #
143
+ # == Parameters
144
+ # +value+:: an arbitrary integer to be checked.
145
+ # +generator+:: optional. A pseudo-prime generator.
146
+ def prime?(value, generator = Prime::Generator23.new)
147
+ value = -value if value < 0
148
+ return false if value < 2
149
+ for num in generator
150
+ q,r = value.divmod num
151
+ return true if q < num
152
+ return false if r == 0
153
+ end
154
+ end
155
+
156
+ # Re-composes a prime factorization and returns the product.
157
+ #
158
+ # == Parameters
159
+ # +pd+:: Array of pairs of integers. The each internal
160
+ # pair consists of a prime number -- a prime factor --
161
+ # and a natural number -- an exponent.
162
+ #
163
+ # == Example
164
+ # For [[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]], it returns
165
+ # p_1**e_1 * p_2**e_2 * .... * p_n**e_n.
166
+ #
167
+ # Prime.int_from_prime_division([[2,2], [3,1]]) #=> 12
168
+ def int_from_prime_division(pd)
169
+ pd.inject(1){|value, (prime, index)|
170
+ value *= prime**index
171
+ }
172
+ end
173
+
174
+ # Returns the factorization of +value+.
175
+ #
176
+ # == Parameters
177
+ # +value+:: An arbitrary integer.
178
+ # +generator+:: Optional. A pseudo-prime generator.
179
+ # +generator+.succ must return the next
180
+ # pseudo-prime number in the ascendent
181
+ # order. It must generate all prime numbers,
182
+ # but may generate non prime numbers.
183
+ #
184
+ # === Exceptions
185
+ # +ZeroDivisionError+:: when +value+ is zero.
186
+ #
187
+ # == Example
188
+ # For an arbitrary integer
189
+ # n = p_1**e_1 * p_2**e_2 * .... * p_n**e_n,
190
+ # prime_division(n) returns
191
+ # [[p_1, e_1], [p_2, e_2], ...., [p_n, e_n]].
192
+ #
193
+ # Prime.prime_division(12) #=> [[2,2], [3,1]]
194
+ #
195
+ def prime_division(value, generator= Prime::Generator23.new)
196
+ raise ZeroDivisionError if value == 0
197
+ if value < 0
198
+ value = -value
199
+ pv = [[-1, 1]]
200
+ else
201
+ pv = []
202
+ end
203
+ for prime in generator
204
+ count = 0
205
+ while (value1, mod = value.divmod(prime)
206
+ mod) == 0
207
+ value = value1
208
+ count += 1
209
+ end
210
+ if count != 0
211
+ pv.push [prime, count]
212
+ end
213
+ break if value1 <= prime
214
+ end
215
+ if value > 1
216
+ pv.push [value, 1]
217
+ end
218
+ return pv
219
+ end
220
+
221
+ # An abstract class for enumerating pseudo-prime numbers.
222
+ #
223
+ # Concrete subclasses should override succ, next, rewind.
224
+ class PseudoPrimeGenerator
225
+ include Enumerable
226
+
227
+ def initialize(ubound = nil)
228
+ @ubound = ubound
229
+ end
230
+
231
+ def upper_bound=(ubound)
232
+ @ubound = ubound
233
+ end
234
+ def upper_bound
235
+ @ubound
236
+ end
237
+
238
+ # returns the next pseudo-prime number, and move the internal
239
+ # position forward.
240
+ #
241
+ # +PseudoPrimeGenerator+#succ raises +NotImplementedError+.
242
+ def succ
243
+ raise NotImplementedError, "need to define `succ'"
244
+ end
245
+
246
+ # alias of +succ+.
247
+ def next
248
+ raise NotImplementedError, "need to define `next'"
249
+ end
250
+
251
+ # Rewinds the internal position for enumeration.
252
+ #
253
+ # See +Enumerator+#rewind.
254
+ def rewind
255
+ raise NotImplementedError, "need to define `rewind'"
256
+ end
257
+
258
+ # Iterates the given block for each prime numbers.
259
+ def each(&block)
260
+ return self.dup unless block
261
+ if @ubound
262
+ last_value = nil
263
+ loop do
264
+ prime = succ
265
+ break last_value if prime > @ubound
266
+ last_value = block.call(prime)
267
+ end
268
+ else
269
+ loop do
270
+ block.call(succ)
271
+ end
272
+ end
273
+ end
274
+
275
+ # see +Enumerator+#with_index.
276
+ alias with_index each_with_index
277
+
278
+ # see +Enumerator+#with_object.
279
+ def with_object(obj)
280
+ return enum_for(:with_object) unless block_given?
281
+ each do |prime|
282
+ yield prime, obj
283
+ end
284
+ end
285
+ end
286
+
287
+ # An implementation of +PseudoPrimeGenerator+.
288
+ #
289
+ # Uses +EratosthenesSieve+.
290
+ class EratosthenesGenerator < PseudoPrimeGenerator
291
+ def initialize
292
+ @last_prime = nil
293
+ super
294
+ end
295
+
296
+ def succ
297
+ @last_prime = @last_prime ? EratosthenesSieve.instance.next_to(@last_prime) : 2
298
+ end
299
+ def rewind
300
+ initialize
301
+ end
302
+ alias next succ
303
+ end
304
+
305
+ # An implementation of +PseudoPrimeGenerator+ which uses
306
+ # a prime table generated by trial division.
307
+ class TrialDivisionGenerator<PseudoPrimeGenerator
308
+ def initialize
309
+ @index = -1
310
+ super
311
+ end
312
+
313
+ def succ
314
+ TrialDivision.instance[@index += 1]
315
+ end
316
+ def rewind
317
+ initialize
318
+ end
319
+ alias next succ
320
+ end
321
+
322
+ # Generates all integer which are greater than 2 and
323
+ # are not divided by 2 nor 3.
324
+ #
325
+ # This is a pseudo-prime generator, suitable on
326
+ # checking primality of a integer by brute force
327
+ # method.
328
+ class Generator23<PseudoPrimeGenerator
329
+ def initialize
330
+ @prime = 1
331
+ @step = nil
332
+ super
333
+ end
334
+
335
+ def succ
336
+ loop do
337
+ if (@step)
338
+ @prime += @step
339
+ @step = 6 - @step
340
+ else
341
+ case @prime
342
+ when 1; @prime = 2
343
+ when 2; @prime = 3
344
+ when 3; @prime = 5; @step = 2
345
+ end
346
+ end
347
+ return @prime
348
+ end
349
+ end
350
+ alias next succ
351
+ def rewind
352
+ initialize
353
+ end
354
+ end
355
+
356
+
357
+
358
+
359
+ # Internal use. An implementation of prime table by trial division method.
360
+ class TrialDivision
361
+ include Singleton
362
+
363
+ def initialize # :nodoc:
364
+ # These are included as class variables to cache them for later uses. If memory
365
+ # usage is a problem, they can be put in Prime#initialize as instance variables.
366
+
367
+ # There must be no primes between @primes[-1] and @next_to_check.
368
+ @primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
369
+ # @next_to_check % 6 must be 1.
370
+ @next_to_check = 103 # @primes[-1] - @primes[-1] % 6 + 7
371
+ @ulticheck_index = 3 # @primes.index(@primes.reverse.find {|n|
372
+ # n < Math.sqrt(@@next_to_check) })
373
+ @ulticheck_next_squared = 121 # @primes[@ulticheck_index + 1] ** 2
374
+ end
375
+
376
+ # Returns the cached prime numbers.
377
+ def cache
378
+ return @primes
379
+ end
380
+ alias primes cache
381
+ alias primes_so_far cache
382
+
383
+ # Returns the +index+th prime number.
384
+ #
385
+ # +index+ is a 0-based index.
386
+ def [](index)
387
+ while index >= @primes.length
388
+ # Only check for prime factors up to the square root of the potential primes,
389
+ # but without the performance hit of an actual square root calculation.
390
+ if @next_to_check + 4 > @ulticheck_next_squared
391
+ @ulticheck_index += 1
392
+ @ulticheck_next_squared = @primes.at(@ulticheck_index + 1) ** 2
393
+ end
394
+ # Only check numbers congruent to one and five, modulo six. All others
395
+
396
+ # are divisible by two or three. This also allows us to skip checking against
397
+ # two and three.
398
+ @primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?
399
+ @next_to_check += 4
400
+ @primes.push @next_to_check if @primes[2..@ulticheck_index].find {|prime| @next_to_check % prime == 0 }.nil?
401
+ @next_to_check += 2
402
+ end
403
+ return @primes[index]
404
+ end
405
+ end
406
+
407
+ # Internal use. An implementation of eratosthenes's sieve
408
+ class EratosthenesSieve
409
+ include Singleton
410
+
411
+ BITS_PER_ENTRY = 16 # each entry is a set of 16-bits in a Fixnum
412
+ NUMS_PER_ENTRY = BITS_PER_ENTRY * 2 # twiced because even numbers are omitted
413
+ ENTRIES_PER_TABLE = 8
414
+ NUMS_PER_TABLE = NUMS_PER_ENTRY * ENTRIES_PER_TABLE
415
+ FILLED_ENTRY = (1 << NUMS_PER_ENTRY) - 1
416
+
417
+ def initialize # :nodoc:
418
+ # bitmap for odd prime numbers less than 256.
419
+ # For an arbitrary odd number n, @tables[i][j][k] is
420
+ # * 1 if n is prime,
421
+ # * 0 if n is composite,
422
+ # where i,j,k = indices(n)
423
+ @tables = [[0xcb6e, 0x64b4, 0x129a, 0x816d, 0x4c32, 0x864a, 0x820d, 0x2196].freeze]
424
+ end
425
+
426
+ # returns the least odd prime number which is greater than +n+.
427
+ def next_to(n)
428
+ n = (n-1).div(2)*2+3 # the next odd number to given n
429
+ table_index, integer_index, bit_index = indices(n)
430
+ loop do
431
+ extend_table until @tables.length > table_index
432
+ for j in integer_index...ENTRIES_PER_TABLE
433
+ if !@tables[table_index][j].zero?
434
+ for k in bit_index...BITS_PER_ENTRY
435
+ return NUMS_PER_TABLE*table_index + NUMS_PER_ENTRY*j + 2*k+1 if !@tables[table_index][j][k].zero?
436
+ end
437
+ end
438
+ bit_index = 0
439
+ end
440
+ table_index += 1; integer_index = 0
441
+ end
442
+ end
443
+
444
+ private
445
+ # for an odd number +n+, returns (i, j, k) such that @tables[i][j][k] represents primarity of the number
446
+ def indices(n)
447
+ # binary digits of n: |0|1|2|3|4|5|6|7|8|9|10|11|....
448
+ # indices: |-| k | j | i
449
+ # because of NUMS_PER_ENTRY, NUMS_PER_TABLE
450
+
451
+ k = (n & 0b00011111) >> 1
452
+ j = (n & 0b11100000) >> 5
453
+ i = n >> 8
454
+ return i, j, k
455
+ end
456
+
457
+ def extend_table
458
+ lbound = NUMS_PER_TABLE * @tables.length
459
+ ubound = lbound + NUMS_PER_TABLE
460
+ new_table = [FILLED_ENTRY] * ENTRIES_PER_TABLE # which represents primarity in lbound...ubound
461
+ (3..Integer(Math.sqrt(ubound))).step(2) do |p|
462
+ i, j, k = indices(p)
463
+ next if @tables[i][j][k].zero?
464
+
465
+ start = (lbound.div(p)+1)*p # least multiple of p which is >= lbound
466
+ start += p if start.even?
467
+ (start...ubound).step(2*p) do |n|
468
+ _, j, k = indices(n)
469
+ new_table[j] &= FILLED_ENTRY^(1<<k)
470
+ end
471
+ end
472
+ @tables << new_table.freeze
473
+ end
474
+ end
475
+
476
+ # Provides a +Prime+ object with compatibility to Ruby 1.8 when instanciated via +Prime+.+new+.
477
+ module OldCompatibility
478
+ # Returns the next prime number and forwards internal pointer.
479
+ def succ
480
+ @generator.succ
481
+ end
482
+ alias next succ
483
+
484
+ # Overwrites Prime#each.
485
+ #
486
+ # Iterates the given block over all prime numbers. Note that enumeration starts from
487
+ # the current position of internal pointer, not rewound.
488
+ def each(&block)
489
+ return @generator.dup unless block_given?
490
+ loop do
491
+ yield succ
492
+ end
493
+ end
494
+ end
495
+ end
@@ -0,0 +1,9 @@
1
+ module Math
2
+ def self.cbrt(x)
3
+ (x.to_f**(1.0/3.0)).round.to_f
4
+ end unless Math.methods.any?{|m| m.to_s == 'cbrt'}
5
+
6
+ def self.log2(x)
7
+ Math.log(x) / Math.log(2)
8
+ end unless Math.methods.any?{|m| m.to_s == 'log2'}
9
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ class Integer
3
+ alias :ω :number_of_distinct_prime_factors
4
+ alias :Ω :number_of_prime_factors
5
+ alias σ :sum_of_divisors
6
+ alias :möbius :mobius
7
+ alias :μ :mobius
8
+ end
data/lib/numb/self.rb ADDED
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def self?
4
+ # Formula from: Kaprekar, D. R. The Mathematics of New Self-Numbers
5
+ # Devaiali (1963): 19 - 20
6
+ dr_star = digital_root.odd? ? (digital_root + 9) / 2 : digital_root / 2
7
+ 0.upto(digits.size).none? do |i|
8
+ (self - dr_star - 9 * i) + (self - dr_star - 9 * i).sod == self
9
+ end
10
+ end
11
+ alias :colombian? :self?
12
+ alias :devlai? :self?
13
+ end
@@ -0,0 +1,9 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def self_descriptive?(base=10)
4
+ dig = digits
5
+ return false unless digits.size == base
6
+ dig.each_with_index{|d,i| return false unless dig.count(i) == d}
7
+ true
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def semi_perfect?
4
+ return false if deficient?
5
+ return true if perfect?
6
+ divisors = proper_positive_divisors
7
+ 1.upto(divisors.size-1) do |size|
8
+ divisors.combination(size) do |comb|
9
+ return true if comb.reduce(:+) == self
10
+ end
11
+ end
12
+ false
13
+ end
14
+ alias :pseudo_perfect? :semi_perfect?
15
+ end
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def semiprime?
4
+ prime_factors.size == 2
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def smarandache_wellin?
4
+ prime_str = ''
5
+ Prime.each do |prime|
6
+ prime_str << prime.to_s
7
+ return true if prime_str == to_s
8
+ return false if prime_str.length >= to_s.length
9
+ end
10
+ end
11
+ end
data/lib/numb/smith.rb ADDED
@@ -0,0 +1,7 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def smith?
4
+ return false if prime?
5
+ digital_sum == prime_division.map{|d,e| d.digital_sum * e}.reduce(:+)
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def sphenic?
4
+ (prime_factors.size == 3) &&
5
+ (prime_factors.uniq.size == 3) &&
6
+ (prime_factors.reduce(:*) == self)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def square?
4
+ return false if self < 0
5
+ root = Math.sqrt(self)
6
+ root == root.floor
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def square_free?
4
+ positive_divisors.reject{|d| d==1}.none? {|d| d.square?}
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def triangular?
4
+ return false if self < 0
5
+ root = Math.sqrt(8 * self + 1)
6
+ root == root.floor
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def trimorphic?
4
+ (self ** 3).to_s.end_with? self.to_s
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def undulating?
4
+ dig = digits
5
+ return false unless digits.size >= 3 and digits[0] != digits[1]
6
+ dig.each_with_index do |d,i|
7
+ return false unless i.odd? ? d == dig[1] : d == dig[0]
8
+ end
9
+ true
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def vampire?
4
+ return false unless !prime? and digits.size.even?
5
+ digits.permutation.map do |perm|
6
+ [:first,:last].map {|pos| perm.send(pos,(digits.size/2)).join.to_i }.sort
7
+ end.uniq.any? do |fangs|
8
+ fangs.reduce(:*) == self
9
+ end
10
+ end
11
+ end
data/lib/numb/weird.rb ADDED
@@ -0,0 +1,8 @@
1
+ # coding: utf-8
2
+ class Integer
3
+ def weird?
4
+ return false unless self > 0
5
+ return false if odd? && self < (10 ** 17)
6
+ not semi_perfect? and abundant?
7
+ end
8
+ end