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]}); }