# HG changeset patch # User Shlomi Fish # Date 1328717717 -7200 # Node ID c9f3e67e0eaebf7cf006f325847c11cf0b4abd4b # Parent 810af966a391c80a9c63afcd27edf17d4bd2bbc9 Add more to Euler #152 - still not good enough. diff --git a/project-euler/152/euler-152.pl b/project-euler/152/euler-152.pl --- a/project-euler/152/euler-152.pl +++ b/project-euler/152/euler-152.pl @@ -4,6 +4,7 @@ use warnings; use Math::BigRat only => 'GMP'; +use List::MoreUtils qw(any); sub sq_frac { @@ -34,6 +35,27 @@ return 1; } +sub factorize +{ + my (\$n) = @_; + my @ret; + + my \$factor = 2; + while (\$n > 1) + { + if (\$n % \$factor == 0) + { + push @ret, \$factor; + \$n /= \$factor; + } + else + { + \$factor++; + } + } + return \@ret; +} + my \$target = Math::BigRat->new('1/2'); my \$limit = 80; @@ -46,13 +68,20 @@ my @remaining_sums; -\$remaining_sums[81] = 0; +\$remaining_sums[\$limit+1] = 0; -for my \$n (reverse(2 .. 80)) +for my \$n (reverse(2 .. \$limit)) { \$remaining_sums[\$n] = \$remaining_sums[\$n+1] + sq_frac(\$n); } +my @end_at; +\$end_at[2] = \$limit+1; +for my \$p (@primes) +{ + \$end_at[\$p] = int(\$limit/\$p) * \$p + 1; +} + sub recurse { my (\$start_from, \$so_far, \$sum) = @_; @@ -73,10 +102,17 @@ return; } + my \$factors = factorize(\$sum->denominator()); + + if (any { \$end_at[\$_] <= \$start_from } @\$factors) + { + return; + } + FIRST_LOOP: foreach my \$first (\$start_from .. \$limit) { - my \$new_sum = \$sum + sq_frac(\$first); + my \$new_sum = (\$sum + sq_frac(\$first))->bnorm(); if (\$new_sum > \$target) { return; @@ -121,6 +157,6 @@ return; } -recurse(2, [], 0); +recurse(2, [], Math::BigRat->new('0/1'));