aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-153/james-smith/perl/ch-2.pl50
1 files changed, 48 insertions, 2 deletions
diff --git a/challenge-153/james-smith/perl/ch-2.pl b/challenge-153/james-smith/perl/ch-2.pl
index 457b3cbd80..b04809c552 100644
--- a/challenge-153/james-smith/perl/ch-2.pl
+++ b/challenge-153/james-smith/perl/ch-2.pl
@@ -8,13 +8,25 @@ use Test::More;
use Benchmark qw(cmpthese timethis);
use Data::Dumper qw(Dumper);
+## Prep for tests!
my @f = (1);
push @f, $_*$f[-1] foreach 1..9;
+my @t = map { my $t = $_; map {$t+$_} @f } @f;
+my @q = map { my $t = $_; map {$t+$_} @f } @t;
my @TESTS = ( [ 145, 1 ], [ 125, 0 ], );
-is( is_factorion($_->[0])||0, $_->[1] ) foreach @TESTS;
+is( is_factorion( $_->[0])||0, $_->[1] ) foreach @TESTS;
+is( is_factorion_1k( $_->[0])||0, $_->[1] ) foreach @TESTS;
done_testing();
+say join ', ', get_factorions();
+say join ', ', get_factorions_1k();
+
+cmpthese( 100, {
+ '10' => sub { get_factorions() },
+ '1k' => sub { get_factorions_1k() },
+});
+
## Has to be at most 7 digits as 8x9! < 9_999_999
## We note that 8x9^7 is the maximum possible value
## Further the value of this is 2_540_160. So we note
@@ -23,7 +35,18 @@ done_testing();
## So we are guaranteed to find all values if we
## search as far as this value...
-is_factorion($_) && say for 1 .. 2_177_282;
+## In the 1k method - we cheat and store the sum of 3 factorials for values
+## from 0..999 {along with 2 digit version 0..99 and the previously used 0..9}
+## We have to do this as the sum of "99" isn't the same as the sum "099".
+
+sub get_factorions {
+ @f = (1);
+ push @f, $_*$f[-1] foreach 1..9;
+
+ my @res;
+ is_factorion($_) && push @res,$_ for 1 .. 2_177_282;
+ return @res;
+}
sub is_factorion {
my $t = $_[0];
@@ -31,3 +54,26 @@ sub is_factorion {
return 0;
}
+sub get_factorions_1k {
+ @f = (1);
+ push @f, $_*$f[-1] foreach 1..9;
+ @t = map { my $t = $_; map {$t+$_} @f } @f;
+ @q = map { my $t = $_; map {$t+$_} @f } @t;
+ my @res;
+ is_factorion_1k($_) && push @res,$_ for 1 .. 2_177_282;
+ return @res;
+}
+
+sub is_factorion_1k {
+ my $t = $_[0];
+ return $t == (
+ $t >= 1e6 ? $f[ $t/1e6 ] + $q[ ($t/1e3)%1e3 ] + $q[ $t%1e3 ]
+ : $t >= 1e5 ? $q[ $t/1e3 ] + $q[ $t%1e3 ]
+ : $t >= 1e4 ? $t[ $t/1e3 ] + $q[ $t%1e3 ]
+ : $t >= 1e3 ? $f[ $t/1e3 ] + $q[ $t%1e3 ]
+ : $t >= 100 ? $q[ $t ]
+ : $t >= 10 ? $t[ $t ]
+ : $f[ $t ]
+ );
+}
+