751 Concatenation Coincidence.pl 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #!/usr/bin/perl
  2. # Author: Trizen
  3. # Date: 23 March 2022
  4. # https://github.com/trizen
  5. # Concatenation Coincidence
  6. # https://projecteuler.net/problem=751
  7. # Runtime: 0.182s
  8. use 5.020;
  9. use warnings;
  10. use Memoize qw(memoize);
  11. use experimental qw(signatures);
  12. use Math::AnyNum qw(:overload :all);
  13. memoize('b');
  14. sub b ($n, $t) {
  15. return $t if ($n == 1);
  16. floor(b($n - 1, $t)) * (b($n - 1, $t) - floor(b($n - 1, $t)) + 1);
  17. }
  18. (join(' ', map { floor(b($_, 2.956938891377988)) } 1 .. 10) eq join(' ', map { fibonacci($_) } 3 .. 12))
  19. or die "Error!";
  20. my $PREC = 24;
  21. my $PREFIX = 2;
  22. sub f ($t) {
  23. my @terms;
  24. for (my $k = 1 ; length(join('', @terms)) <= $PREC ; ++$k) {
  25. push @terms, floor(b($k, $t));
  26. }
  27. my $lead = shift(@terms);
  28. my $dec = Math::AnyNum->new(join('', @terms));
  29. my $x = $lead + ($dec / 10**(ilog10($dec) + 1));
  30. say sprintf("%s <=> %s", float($t), float($x));
  31. return $x;
  32. }
  33. my $theta = bsearch_le(
  34. 10**$PREC,
  35. 10**($PREC + 1),
  36. sub ($k) {
  37. my $t = $PREFIX + ($k / 10**(ilog10($k) + 1));
  38. $t <=> f($t);
  39. }
  40. );
  41. say("Answer: ", Math::AnyNum->new("$PREFIX.$theta")->round(-$PREC));