diff options
| -rw-r--r-- | challenge-171/james-smith/README.md | 11 | ||||
| -rw-r--r-- | challenge-171/james-smith/perl/ch-1.pl | 45 |
2 files changed, 35 insertions, 21 deletions
diff --git a/challenge-171/james-smith/README.md b/challenge-171/james-smith/README.md index 2e741787b9..40d3f0081a 100644 --- a/challenge-171/james-smith/README.md +++ b/challenge-171/james-smith/README.md @@ -74,7 +74,7 @@ In this example we merge the factor/sum stages together into a single loop. ```perl sub is_abundant { my $s = 1 - (my $t = pop); - $s += $t%$_ ? 0 : $t-$_*$_ ? $_+$t/$_ : $_ for 2 .. sqrt $t; + $s += $t%$_ ? 0 : $_ + ( $t-$_*$_ && $t/$_ ) for 2 .. sqrt $t; $s>0 } ``` @@ -93,10 +93,11 @@ I need a function to test task 2 out - so thought this would be a good problem. We have the three stages -> factor -> sum -> test which we can male into 3 subs which we can compose together. Note we still do the `-n` trick to avoid passing `n` through from method to method. ```perl -my $is_abundant = compose - sub { pop > 0 }, ## check - sub { my $s = 0; $s+=$_ for @_; $s }, ## sum - sub { my $t = pop; -$t, 1, map { $t%$_ ? () : $t-$_*$_ ? ($_,$t/$_) : $_ } 2..sqrt $t }; ## factor +my $factor = sub { my $t = pop; -$t, 1, map { $t%$_ ? () : $t-$_*$_ ? ($_,$t/$_) : $_ } 2..sqrt $t }; +my $sum = sub { my $s = 0; $s+=$_ for @_; $s }; +my $check = sub { pop > 0 }; + +my $is_abundant = compose $check, $sum, $factor; my $t = 1; $is_abundant->($t+=2) ? say $t : redo for 1..20; ``` diff --git a/challenge-171/james-smith/perl/ch-1.pl b/challenge-171/james-smith/perl/ch-1.pl index 6a6f4b1f6f..3356801307 100644 --- a/challenge-171/james-smith/perl/ch-1.pl +++ b/challenge-171/james-smith/perl/ch-1.pl @@ -7,42 +7,55 @@ use feature qw(say); my $N = $ARGV[0]//20; ## + +##---------------------------------------------------------------------- ## Fron task 1 we steal our "recursive" compose function ## so we can stitch methods together. -## +##---------------------------------------------------------------------- sub compose { my($g,$f) = pop; @_ && ($f = pop) ? compose( @_, sub { $f->($g->(@_)) } ) : $g } +##---------------------------------------------------------------------- +## Create the two is_abundant methods - a simple sub and our composite +## first-class function. +##---------------------------------------------------------------------- + sub is_abundant { my $s = 1 - (my $t = pop); - $s += $t%$_ ? 0 : $t-$_*$_ ? $_+$t/$_ : $_ for 2 .. sqrt $t; + $s += $t%$_ ? 0 : $_ + ( $t-$_*$_ && $t/$_ ) for 2 .. sqrt $t; $s>0 } +## Create first-class functions for the three stages... + + ## Find factors... We add -$t to the list as we want to add up sum + ## of factors > $t... +my $factor = sub { my $t = pop; + -$t, 1, map { $t%$_ ? () : $t-$_*$_ ? ($_,$t/$_) : $_ } 2..sqrt $t }; + +my $sum = sub { my $s = 0; $s+=$_ for @_; $s }; -my $is_abundant = compose - ## Check value is greater than 0. - sub { pop > 0 }, - ## Simple sum... - sub { my $s = 0; - $s+=$_ for @_; - $s - }, - ## Find factors... We add -$t to the list - ## As we want to add up sum of factors > $t... - sub { my $t = pop; - -$t, 1, map { $t%$_ ? () : $t-$_*$_ ? ($_,$t/$_) : $_ } 2..sqrt $t - }; +my $check = sub { pop > 0 }; + +## Combine them into a single first class function... + +my $is_abundant = compose $check, $sum, $factor; + +##---------------------------------------------------------------------- +## Generate output from the two methods... +##---------------------------------------------------------------------- ## Loop one - using the simple function... + say ''; my $k = 1; is_abundant($k+=2) ? say $k : redo for 1..$N; say ''; -## Loop two - using the chained methods using compose... +## Loop two - using the first-class function.. + my $t = 1; $is_abundant->($t+=2) ? say $t : redo for 1..$N; say ''; |
