my @even = 0, 2, 4 ... { $_ + 2};
my @powers = 1, 2, 4 ... { $_ * 2 };
my @fib = 1, 1, 2 ... { $^a + $^b};
####
my @ints = 1, 2, 3, 4 ... *;
my @even = 0, 2, 4, 6 ... *;
my @powers = 1, 2, 4, 8 ... *;
####
1, 3, 5 ... * # odd numbers
1, 2, 4 ... * # powers of 2
####
sub series(@items, $recursion_level = 2) {
return if $recursion_level < 0;
return if @items < 2;
# are all items the same?
return @items[0] if [==] @items;
# detect arithmetic sequences
my @diffs = map { @items[$_+1] - @items[$_] }, 0 .. (@items - 2);
my $d = series(@diffs, $recursion_level - 1);
return @items[*-1] + $d if $d.defined;
# detect geometric sequences
my $r = try {
my @ratios = map { @items[$_+1] / @items[$_] }, 0 .. (@items - 2);
series(@ratios, $recursion_level - 1);
}
return @items[*-1] * $r if $r.defined;
# give up
return;
}
####
use List::MoreUtils qw(all);
sub series {
_series(2, @_);
}
sub _series {
my $recursion_level = shift;
return if $recursion_level < 0;
return if @_ < 2;
my $first = $_[0];
if (all { $_ == $first } @_) {
return $first;
}
my @a = map { $_[$_+1] - $_[$_] } 0 .. (@_ - 2);
my $r = _series($recursion_level - 1, @a);
return $_[-1] + $r if defined $r;
# catch division by zero
$r = eval {
@a = map { $_[$_+1] / $_[$_] } 0 ... (@_ - 2);
_series($recursion_level - 1, @a);
};
return $_[-1] * $r if defined $r;
return;
}
####
#!/usr/bin/perl
use strict;
use warnings;
use Test::More qw(no_plan);
sub series {
# your code here.
}
my @tests = (
[[1], undef],
[[1, 1], 1],
[[0, 0], 0],
[[1, 2], undef],
[[0, 1, 2], 3],
[[1, 0, -1], -2],
[[1, 2, 3], 4],
[[1, 2, 4], 8], # powers
[[2, 4, 8], 16],
[[1, 3, 9], 27],
[[1, -1, 1, -1], 1], # alternations
[[-1, 1, -1, 1], -1],
[[1, 0, 1, 0], 1],
[[0, 1, 0, 1], 0],
[[1, 1, 2, 3, 5], 8], # fibonacci
[[0, 1, 1, 2, 3], 8],
[[1, 2, 3, 5, 8], 13],
[[1, 2, 6, 24, 120], 720], # factorials
[[1, 0, 0, 1], undef],
[[1, 2, 3, 1], undef],
);
for my $t (@tests) {
my $expected = defined $t->[1] ? $t->[1] : 'undef';
my $result = series(@{$t->[0]});
$result = 'undef' unless defined $result;
is $result, $expected, "seq " . join(', ', @{$t->[0]});
}