http://qs321.pair.com?node_id=911973


in reply to Filling in missing values in an array

My take (with tests):

#!/usr/local/bin/perl use strict; use warnings FATAL => 'all'; sub fill_in_the_blanks { my @arr = @_; die "No values found" if @arr && 0 == grep $_ ne '_', @arr; for (my $left = 0; $left < @arr; $left++) { next unless $arr[$left] eq '_'; my $right = $left; $right++ while $right < $#arr && $arr[$right+1] eq '_'; if ($left == 0) { # NULLs at the left $arr[$_] = $arr[$right+1] for $left..$right; } elsif ($right == $#arr) { # NULLs at the right $arr[$_] = $arr[$left-1] for $left..$right; } elsif ($left == $right) { # single $arr[$left] = ($arr[$left-1] + $arr[$left+1]) / 2; } else { $arr[$left ] = $arr[$left -1]; $arr[$right] = $arr[$right+1]; } } return @arr; } use Test::Most; is_deeply [fill_in_the_blanks(qw< >)], [qw< >], "( )"; is_deeply [fill_in_the_blanks(qw<1>)], [qw<1>], "(1)"; throws_ok { fill_in_the_blanks(qw< _ >) } qr{No values found}, "( _ + )"; throws_ok { fill_in_the_blanks(qw< _ _ >) } qr{No values found}, "( _ +_ )"; throws_ok { fill_in_the_blanks(qw<_ _ _>) } qr{No values found}, "(_ _ + _)"; is_deeply [fill_in_the_blanks(qw<1 _ 1>)], [qw<1 1 1>], "(1 _ 1)"; is_deeply [fill_in_the_blanks(qw<1 _ 3>)], [qw<1 2 3>], "(1 _ 3)"; is_deeply [fill_in_the_blanks(qw<1 _ _ 3>)], [qw<1 1 3 3>], "(1 _ + _ 3)"; is_deeply [fill_in_the_blanks(qw<1 _ _ _ 3>)], [qw<1 1 2 3 3>], "(1 _ +_ _ 3)"; is_deeply [fill_in_the_blanks(qw<1 _>)], [qw<1 1>], "(1 _)"; is_deeply [fill_in_the_blanks(qw<1 _ _>)], [qw<1 1 1>], "(1 _ _)"; is_deeply [fill_in_the_blanks(qw<_ 1>)], [qw<1 1>], "(_ 1)"; is_deeply [fill_in_the_blanks(qw<_ _ 1>)], [qw<1 1 1>], "(_ _ 1)"; is_deeply [fill_in_the_blanks(qw<4 _ _ _ 5>)], [qw<4 4 4.5 5 5>], "dhu +ang90"; done_testing;

The results...

ok 1 - ( ) ok 2 - (1) ok 3 - ( _ ) ok 4 - ( _ _ ) ok 5 - (_ _ _) ok 6 - (1 _ 1) ok 7 - (1 _ 3) ok 8 - (1 _ _ 3) ok 9 - (1 _ _ _ 3) ok 10 - (1 _) ok 11 - (1 _ _) ok 12 - (_ 1) ok 13 - (_ _ 1) ok 14 - dhuang90 1..14

An interesting little problem. It has lots of edge cases and so makes a nice code kata. Thank for posting it.

Replies are listed 'Best First'.
Re^2: Filling in missing values in an array
by Neighbour (Friar) on Jun 29, 2011 at 14:32 UTC
    Very informative...this helps me get the hang of tests :)
    Though I'm not quite sure how tests 3-5 are supposed to go. If I let the sub execute die "No values found" when that is the case, the app dies instead of showing testresults.
      Though I'm not quite sure how tests 3-5 are supposed to go
      Neither was I! So I made it die (a.k.a throws an exception) when the array consists only of NULLs. Garbage in, garbage out, as we used to say. Exceptions prevent the garbage leaking out.

      If you decide it should do something other than die, just change this line:

      die "No values found" if @arr && 0 == grep $_ ne '_', @arr;
        Yea, but when it dies, the tests are never executed (in my case). That's probably not what's supposed to happen :).