is_lucas-carmichael_number.sf 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 30 March 2019
  4. # https://github.com/trizen
  5. # Prove if a given number `n` is a Lucas-Carmichael number, using the divisors of `n+1`.
  6. # See also:
  7. # https://en.wikipedia.org/wiki/Lucas%E2%80%93Carmichael_number
  8. # OEIS:
  9. # https://oeis.org/A322702 -- a(n) is the product of primes p such that p+1 divides n.
  10. # https://oeis.org/A006972 -- Lucas-Carmichael numbers: squarefree composite numbers n such that p | n => p+1 | n+1.
  11. func lucas_bernoulli_denominator (n) { # A322702
  12. n.divisors.grep {|d|
  13. d-1 -> is_prob_prime
  14. }.prod {|d|
  15. d-1
  16. }
  17. }
  18. func is_lucas_carmichael (n) {
  19. # Make sure `n` is not prime
  20. return false if (n<=1 || n.is_prime)
  21. # Is a Lucas-Carmichael number iff `n` divides Product_{d|n+1, d-1 is prime} (d-1).
  22. n.divides(lucas_bernoulli_denominator(n+1))
  23. }
  24. func is_lucas_carmichael_faster (n) {
  25. var f = n.factor_exp
  26. f.len >= 3 && f.all { .tail == 1 } && f.all {|p| (n+1) % (p.head+1) == 0 }
  27. }
  28. say is_lucas_carmichael.first(5) #=> [399, 935, 2015, 2915, 4991]
  29. say is_lucas_carmichael_faster.first(5) #=> [399, 935, 2015, 2915, 4991]
  30. __END__
  31. 399, 935, 2015, 2915, 4991, 5719, 7055, 8855, 12719, 18095