aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-171/james-smith/README.md11
-rw-r--r--challenge-171/james-smith/perl/ch-1.pl45
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 '';