Skip to content

Instantly share code, notes, and snippets.

@leedo
Last active December 19, 2015 06:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leedo/735a5f09350bd2d50d33 to your computer and use it in GitHub Desktop.
Save leedo/735a5f09350bd2d50d33 to your computer and use it in GitHub Desktop.
sub METAOP_REDUCE_LEFT(\op, :$triangle) {
if ($triangle) {
return sub (*@values) {
return () unless @values.gimme(1);
GATHER({
my $result := @values.shift;
take $result;
take ($result := op.($result, @values.shift))
while @values.gimme(1);
}, :infinite(@values.infinite))
}
}
multi sub reduce (*@values) {
return op.() unless @values.gimme(1);
my $result := @values.shift;
return op.($result) unless @values.gimme(1);
my int $i;
while my int $c = @values.gimme(1000) {
$i = 0;
$result := op.($result, @values.shift)
while ($i = $i + 1) <= $c;
}
$result;
}
# Range optimizations
multi sub reduce ((Range $values)) {
if (op === &infix:<+> and Int === all($values.min.WHAT, $values.max.WHAT)) {
my $min = $values.excludes_min ?? $values.min + 1 !! $values.min;
my $max = $values.excludes_max ?? $values.max - 1 !! $values.max;
return (($max - $min + 1) * ($max + $min)) / 2;
}
return reduce($values.list);
}
return &reduce;
}
say [+] 100..1_000_000;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment