aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-137/james-smith/perl/ch-2.pl66
1 files changed, 51 insertions, 15 deletions
diff --git a/challenge-137/james-smith/perl/ch-2.pl b/challenge-137/james-smith/perl/ch-2.pl
index 8951d7c972..12637c00b5 100644
--- a/challenge-137/james-smith/perl/ch-2.pl
+++ b/challenge-137/james-smith/perl/ch-2.pl
@@ -9,7 +9,8 @@ use Benchmark qw(cmpthese timethis);
use Data::Dumper qw(Dumper);
my $MAX = 1e9;
-my $MAX_LARGE = 40;
+my $S_MAX = 1e6;
+my $MULT = 100;
my $COUNT = 500;
my @TESTS = (
[ 56, 0 ],
@@ -18,8 +19,11 @@ my @TESTS = (
[196, 1 ],
);
-is( lychrel( $_->[0]), $_->[1] ) foreach @TESTS;
-is( lychrel_large($_->[0]), $_->[1] ) foreach @TESTS;
+my %seeds;
+my %lychrel;
+
+is( lychrel( $_->[0]), $_->[1] ) for @TESTS;
+is( lychrel_large($_->[0]), $_->[1] ) for @TESTS;
done_testing();
@@ -30,25 +34,57 @@ sub lychrel {
}
sub lychrel_large {
- my($n,$c) = (shift,$COUNT);
- my @n = split //, $n;
- while( $c-- && @n <= $MAX_LARGE ) {
+ my ( $c, @n ) = ( $COUNT, split //, $_[0] );
+ while( $c-- ) {
+ return 0 if (join '', my @r = reverse @n ) eq (join '', @n); ## Check if palindromic
+ ## Add the arrays as if numbers - note this is compact - but does the job!
+ ( $n[$_] += $r[$_] ) > 9 && ($n[$_] -= 10, $_ ? ($n[$_-1]++) : (unshift @n, 1) ) for reverse 0 .. @n-1;
+ }
+ 1;
+}
+
+sub lychrel_large_seed {
+ my ( $c, $n, @n ) = ( $COUNT, $_[0], split //, $_[0] );
+ while( $c-- ) {
my @r = reverse @n;
- return 0 if (join '', @r) eq (join '', @n);
- foreach ( reverse 0 .. @n-1 ) {
- $n[$_] += $r[$_];
- next if $n[$_] < 10;
- $n[$_]-=10;
- $_ ? ($n[$_-1]++) : (unshift @n,1);
- }
+ my $rn = join '', @r;
+ my $nn = join '', @n;
+ return exists $lychrel{$seeds{$rn}} if $r[0] && defined $seeds{$rn};
+ return exists $lychrel{$seeds{$nn}} if defined $seeds{$nn};
+ $seeds{ $rn } = $n if $rn < $S_MAX*$MULT && $r[0];
+ $seeds{ $nn } = $n if $nn < $S_MAX*$MULT;
+ return 0 if $rn eq $nn; ## Check if palindromic
+ ## Add the arrays as if numbers - note this is compact - but does the job!
+ ( $n[$_] += $r[$_] ) > 9 && ($n[$_] -= 10, $_ ? ($n[$_-1]++) : (unshift @n, 1) ) for reverse 0 .. @n-1;
}
1;
}
+use Time::HiRes qw(time);
+my $time = time;
print "Simple:";
-print " $_" foreach grep { lychrel $_ } 10..1000;
+print " $_" for grep { lychrel $_ } 10..1000;
+print "** time ", time - $time;
+
+foreach my $n (10..$S_MAX) {
+ if( defined $seeds{$n} ) {
+ $lychrel{$n}++ if exists $lychrel{$seeds{$n}};
+ next;
+ }
+ $lychrel{$n}=1 if lychrel_large_seed($n);
+}
+print "\nSieve: ";
+print join " ", sort { $a <=> $b } keys %lychrel;
+print "** time ", time - $time;
+print "\n\n";
+
+$time = time;
print "\nLarge: ";
-print " $_" foreach grep { lychrel_large $_ } 10..1000;
+print " $_" for grep { lychrel_large $_ } 10..$S_MAX;
+print "** time ", time - $time;
print "\n\n";
+$time = time;
+
+