count_of_k-omega_primes.pl 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 14 March 2021
  4. # https://github.com/trizen
  5. # Count the number of k-omega primes <= n.
  6. # Definition:
  7. # k-omega primes are numbers n such that omega(n) = k.
  8. # See also:
  9. # https://en.wikipedia.org/wiki/Almost_prime
  10. # https://en.wikipedia.org/wiki/Prime_omega_function
  11. use 5.020;
  12. use warnings;
  13. use ntheory qw(:all);
  14. use experimental qw(signatures);
  15. sub omega_prime_count_rec ($n, $k = 1) {
  16. if ($k == 1) {
  17. return prime_power_count($n);
  18. }
  19. my $count = 0;
  20. sub ($m, $p, $k, $s = rootint(divint($n, $m), $k), $j = 1) {
  21. if ($k == 2) {
  22. for (; $p <= $s ; ++$j) {
  23. my $r = next_prime($p);
  24. for (my $t = mulint($m, $p) ; $t <= $n ; $t = mulint($t, $p)) {
  25. my $w = divint($n, $t);
  26. if ($r > $w) {
  27. last;
  28. }
  29. $count += prime_count($w) - $j;
  30. for (my $r2 = $r ; $r2 <= $w ; $r2 = next_prime($r2)) {
  31. my $u = vecprod($t, $r2, $r2);
  32. if ($u > $n) {
  33. last;
  34. }
  35. for (; $u <= $n ; $u = mulint($u, $r2)) {
  36. ++$count;
  37. }
  38. }
  39. }
  40. $p = $r;
  41. }
  42. return;
  43. }
  44. for (; $p <= $s ; ++$j) {
  45. my $r = next_prime($p);
  46. for (my $t = mulint($m, $p) ; $t <= $n ; $t = mulint($t, $p)) {
  47. my $s = rootint(divint($n, $t), $k - 1);
  48. last if ($r > $s);
  49. __SUB__->($t, $r, $k - 1, $s, $j + 1);
  50. }
  51. $p = $r;
  52. }
  53. }->(1, 2, $k);
  54. return $count;
  55. }
  56. # Run some tests
  57. foreach my $k (1 .. 10) {
  58. my $upto = pn_primorial($k) + int(rand(1e5));
  59. my $x = omega_prime_count_rec($upto, $k);
  60. my $y = omega_prime_count($k, $upto);
  61. say "Testing: $k with n = $upto -> $x";
  62. $x == $y
  63. or die "Error: $x != $y";
  64. }
  65. say '';
  66. foreach my $k (1 .. 8) {
  67. say("Count of $k-omega primes for 10^n: ", join(', ', map { omega_prime_count_rec(10**$_, $k) } 0 .. 8));
  68. }
  69. __END__
  70. Count of 1-omega primes for 10^n: 0, 7, 35, 193, 1280, 9700, 78734, 665134, 5762859
  71. Count of 2-omega primes for 10^n: 0, 2, 56, 508, 4097, 33759, 288726, 2536838, 22724609
  72. Count of 3-omega primes for 10^n: 0, 0, 8, 275, 3695, 38844, 379720, 3642766, 34800362
  73. Count of 4-omega primes for 10^n: 0, 0, 0, 23, 894, 15855, 208034, 2389433, 25789580
  74. Count of 5-omega primes for 10^n: 0, 0, 0, 0, 33, 1816, 42492, 691209, 9351293
  75. Count of 6-omega primes for 10^n: 0, 0, 0, 0, 0, 25, 2285, 72902, 1490458
  76. Count of 7-omega primes for 10^n: 0, 0, 0, 0, 0, 0, 8, 1716, 80119
  77. Count of 8-omega primes for 10^n: 0, 0, 0, 0, 0, 0, 0, 1, 719