183 Maximum product of parts.pl 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 18 October 2017
  4. # https://github.com/trizen
  5. # https://projecteuler.net/problem=183
  6. # Runtime: 11.360s
  7. use 5.010;
  8. use strict;
  9. use warnings;
  10. use ntheory qw(gcd valuation);
  11. sub maximum_split {
  12. my ($n) = @_;
  13. my $min = 1;
  14. my $max = $n;
  15. while ($min < $max) {
  16. my $mid = ($min + $max) >> 1;
  17. my $x_prev = ($mid - 1) * (log($n) - log($mid - 1));
  18. my $x_curr = ($mid + 0) * (log($n) - log($mid + 0));
  19. my $x_next = ($mid + 1) * (log($n) - log($mid + 1));
  20. if ($x_prev < $x_curr and $x_curr > $x_next) {
  21. return $mid;
  22. }
  23. if ($x_prev < $x_curr and $x_curr < $x_next) {
  24. ++$min;
  25. }
  26. else {
  27. --$max;
  28. }
  29. }
  30. return $min;
  31. }
  32. my $sum = 0;
  33. foreach my $n (5 .. 10000) {
  34. my $M = maximum_split($n);
  35. my $r = $M / gcd($n, $M);
  36. $r /= 2**valuation($r, 2) if ($r % 2 == 0);
  37. $r /= 5**valuation($r, 5) if ($r % 5 == 0);
  38. ($r == 1) ? ($sum -= $n) : ($sum += $n);
  39. }
  40. say $sum;