count_of_smooth_numbers_with_k_factors.pl 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 05 March 2020
  4. # https://github.com/trizen
  5. # Count the number of B-smooth numbers below a given limit, where each number has at least k distinct prime factors.
  6. # Problem inspired by:
  7. # https://projecteuler.net/problem=268
  8. # See also:
  9. # https://en.wikipedia.org/wiki/Smooth_number
  10. use 5.020;
  11. use warnings;
  12. use ntheory qw(:all);
  13. use experimental qw(signatures);
  14. sub smooth_numbers ($initial, $limit, $primes) {
  15. my @h = ($initial);
  16. foreach my $p (@$primes) {
  17. foreach my $n (@h) {
  18. if ($n * $p <= $limit) {
  19. push @h, $n * $p;
  20. }
  21. }
  22. }
  23. return \@h;
  24. }
  25. my $PRIME_MAX = 100; # the prime factors must all be <= this value
  26. my $LEAST_K = 4; # each number must have at least this many distinct prime factors
  27. sub count_smooth_numbers ($limit) {
  28. my $count = 0;
  29. my @primes = @{primes($PRIME_MAX)};
  30. forcomb {
  31. my $c = [@primes[@_]];
  32. my $v = vecprod(@$c);
  33. if ($v <= $limit) {
  34. my $h = smooth_numbers($v, $limit, $c);
  35. foreach my $n (@$h) {
  36. my $new_h = smooth_numbers(1, divint($limit, $n), [grep { $_ < $c->[0] } @primes]);
  37. $count += scalar @$new_h;
  38. }
  39. }
  40. } scalar(@primes), $LEAST_K;
  41. return $count;
  42. }
  43. say "\n# Count of $PRIME_MAX-smooth numbers with at least $LEAST_K distinct prime factors:\n";
  44. foreach my $n (1 .. 16) {
  45. my $count = count_smooth_numbers(powint(10, $n));
  46. say "C(10^$n) = $count";
  47. }
  48. __END__
  49. # Count of 100-smooth numbers with at least 4 distinct prime factors:
  50. C(10^1) = 0
  51. C(10^2) = 0
  52. C(10^3) = 23
  53. C(10^4) = 811
  54. C(10^5) = 8963
  55. C(10^6) = 53808
  56. C(10^7) = 235362
  57. C(10^8) = 866945
  58. C(10^9) = 2855050
  59. C(10^10) = 8668733
  60. C(10^11) = 24692618
  61. C(10^12) = 66682074
  62. C(10^13) = 171957884
  63. C(10^14) = 425693882
  64. C(10^15) = 1015820003
  65. C(10^16) = 2344465914