almost_primes_from_factor_list.pl 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 29 March 2021
  4. # https://github.com/trizen
  5. # Generate all the possible k-almost primes <= n, using a given list of prime factors.
  6. use 5.020;
  7. use ntheory qw(:all);
  8. use experimental qw(signatures);
  9. sub almost_primes ($n, $k, $factors, $squarefree = 0) {
  10. my $factors_end = $#{$factors};
  11. if ($k == 0) {
  12. return (1);
  13. }
  14. if ($k == 1) {
  15. return @$factors;
  16. }
  17. my @list;
  18. sub ($m, $k, $i = 0) {
  19. if ($k == 1) {
  20. my $L = divint($n, $m);
  21. foreach my $j ($i .. $factors_end) {
  22. my $q = $factors->[$j];
  23. last if ($q > $L);
  24. push(@list, mulint($m, $q));
  25. }
  26. return;
  27. }
  28. my $L = rootint(divint($n, $m), $k);
  29. foreach my $j ($i .. $factors_end) {
  30. my $q = $factors->[$j];
  31. last if ($q > $L);
  32. __SUB__->(mulint($m, $q), $k - 1, $j + $squarefree);
  33. }
  34. }->(1, $k);
  35. sort { $a <=> $b } @list;
  36. }
  37. my $n = 1e3; # limit
  38. my @factors = @{primes(11)}; # prime list
  39. foreach my $k (0 .. scalar(@factors)) {
  40. my @divisors = almost_primes($n, $k, \@factors);
  41. printf("%2d-almost primes <= %s: [%s]\n", $k, $n, join(', ', @divisors));
  42. }
  43. __END__
  44. 0-almost primes <= 1000: [1]
  45. 1-almost primes <= 1000: [2, 3, 5, 7, 11]
  46. 2-almost primes <= 1000: [4, 6, 9, 10, 14, 15, 21, 22, 25, 33, 35, 49, 55, 77, 121]
  47. 3-almost primes <= 1000: [8, 12, 18, 20, 27, 28, 30, 42, 44, 45, 50, 63, 66, 70, 75, 98, 99, 105, 110, 125, 147, 154, 165, 175, 231, 242, 245, 275, 343, 363, 385, 539, 605, 847]
  48. 4-almost primes <= 1000: [16, 24, 36, 40, 54, 56, 60, 81, 84, 88, 90, 100, 126, 132, 135, 140, 150, 189, 196, 198, 210, 220, 225, 250, 294, 297, 308, 315, 330, 350, 375, 441, 462, 484, 490, 495, 525, 550, 625, 686, 693, 726, 735, 770, 825, 875]
  49. 5-almost primes <= 1000: [32, 48, 72, 80, 108, 112, 120, 162, 168, 176, 180, 200, 243, 252, 264, 270, 280, 300, 378, 392, 396, 405, 420, 440, 450, 500, 567, 588, 594, 616, 630, 660, 675, 700, 750, 882, 891, 924, 945, 968, 980, 990]