is_practical_number.sf 742 B

12345678910111213141516171819202122232425262728293031
  1. #!/usr/bin/ruby
  2. # Efficient algorithm, due to M. F. Hasler (Jan 13 2013), for efficiently
  3. # checking if a given number is a practical number, using its prime factorization.
  4. # See also:
  5. # https://oeis.org/A005153
  6. # https://rosettacode.org/wiki/Practical_numbers
  7. func is_practical(n) {
  8. n.is_odd && return (n == 1)
  9. n.is_pos || return false
  10. var p = 1
  11. var f = n.factor_exp
  12. f.each_cons(2, {|a,b|
  13. p *= sigma(a.head**a.tail)
  14. b.head > (1 + p) && return false
  15. })
  16. return true
  17. }
  18. say 20.by { is_practical(_) } #=> [1, 2, 4, 6, 8, 12, 16, 18, 20, 24, 28, 30, 32, 36, 40, 42, 48, 54, 56, 60]
  19. say is_practical(666) #=> true
  20. say is_practical(6666) #=> true
  21. say is_practical(66666) #=> false