k-imperfect_numbers.pl 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/perl
  2. # Generate all the k-imperfect numbers less than or equal to n.
  3. # Based on Michel Marcus's algorithm from A328860.
  4. # k-imperfect numbers, are numbers n such that:
  5. # n = k * Sum_{d|n} d * (-1)^Ω(n/d)
  6. # See also:
  7. # https://oeis.org/A206369 -- rho function.
  8. # https://oeis.org/A127724 -- k-imperfect numbers for some k >= 1.
  9. # https://oeis.org/A127725 -- Numbers that are 2-imperfect.
  10. # https://oeis.org/A127726 -- Numbers that are 3-imperfect.
  11. # https://oeis.org/A328860 -- Numbers that are 4-imperfect.
  12. use 5.020;
  13. use warnings;
  14. use ntheory qw(:all);
  15. use List::Util qw(uniq);
  16. use experimental qw(signatures);
  17. sub rho_prime_power ($p, $e) {
  18. my $x = addint(powint($p, $e + 1), $p >> 1);
  19. my $y = $p + 1;
  20. divint($x, $y);
  21. }
  22. sub rho_factors(@F) {
  23. vecprod(map { rho_prime_power($_->[0], $_->[1]) } @F);
  24. }
  25. sub k_imperfect_numbers ($limit, $A, $B = 1) {
  26. my @sol;
  27. my $g = gcd($A, $B);
  28. $A = divint($A, $g);
  29. $B = divint($B, $g);
  30. if ($A == 1) {
  31. return (1) if ($B == 1);
  32. return ();
  33. }
  34. my @f = factor_exp($A);
  35. my $rho = rho_factors(@f);
  36. my ($p, $n) = @{$f[-1]};
  37. my $r = rho_prime_power($p, $n);
  38. for (my $pn = powint($p, $n) ; $pn <= $limit ; $pn = mulint($pn, $p)) {
  39. foreach my $k (__SUB__->(divint($limit, $pn), mulint($A, $r), mulint($B, $pn))) {
  40. push @sol, mulint($pn, $k) if (gcd($pn, $k) == 1);
  41. }
  42. $r = rho_prime_power($p, ++$n);
  43. }
  44. if ($rho == $B) {
  45. push @sol, $A;
  46. }
  47. @sol = grep { $_ <= $limit } @sol;
  48. @sol = sort { $a <=> $b } @sol;
  49. uniq(@sol);
  50. }
  51. say join ', ', k_imperfect_numbers(10**15, 2); # 2-imperfect numbers
  52. say join ', ', k_imperfect_numbers(10**15, 3); # 3-imperfect numbers
  53. __END__
  54. 2, 12, 40, 252, 880, 10880, 75852, 715816960, 62549517598720
  55. 6, 120, 126, 2520, 2640, 30240, 32640, 37800, 37926, 55440, 685440, 758520, 831600, 2600640, 5533920, 6917400, 9102240, 10281600, 11377800, 16687440, 152182800, 206317440, 250311600, 475917120, 866829600, 1665709920, 1881532800, 2082137400, 2147450880, 3094761600, 7660224000, 45096468480, 45807022800, 74547345600, 76324550400, 566341372800, 676447027200, 1265637895200, 1401820992000, 1422467373600, 1769199213600, 10463865984000, 13574037012480, 15634517184000, 19954883520000, 22973689670400, 108844858987200, 122332194129600, 123789805977600, 130728955864320, 152151132369600, 187648552796160, 203610555187200