303 Multiples with small digits.pl 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # Date: 21 August 2016
  4. # License: GPLv3
  5. # Website: https://github.com/trizen
  6. # https://projecteuler.net/problem=303
  7. # Runtime: 1 min 17.65s
  8. use 5.014;
  9. use ntheory qw(todigitstring fromdigits);
  10. my @big;
  11. foreach my $i (1 .. 5) {
  12. push @{$big[9]}, join('', '1' x ($i + 1), '2' x (4 * ($i + 1)));
  13. push @{$big[8]}, join('', '1' x $i, '2' x (4 * $i));
  14. push @{$big[5]}, join('', '1' x $i, '2' x (4 * $i), '0');
  15. }
  16. sub lsd_multiple {
  17. my ($n) = @_;
  18. return $n if $n =~ /^[120]+\z/;
  19. if ( $n > 10
  20. and ($n % 9 == 0)
  21. and defined($big[$n % 10])
  22. and ($n / 9) =~ /^(.)\1*+\z/) {
  23. return $big[$n % 10][length($n) - 2];
  24. }
  25. my $k = (
  26. $n =~ /^[12]/
  27. ? fromdigits($n =~ s/(.)/$1 > 2 ? 2 : $1/ger, 3)
  28. : 3**length($n)
  29. );
  30. while (1) {
  31. my $x = todigitstring($k, 3);
  32. return $x if ($x % $n == 0);
  33. ++$k;
  34. }
  35. }
  36. my $sum = 0;
  37. foreach my $x (1 .. 10_000) {
  38. $sum += lsd_multiple($x) / $x;
  39. }
  40. say $sum;