use strict; use warnings; use Data::Dumper; use Carp; sub subrange_pre_golf { my ($r1,$r2,$ary,$s,$f)=@_; ($s,$f)=(0,$#$ary) unless $s && $f; ($_<$s && $_<$f or $_>$s && $_>$f) and die "Bad range!" for $r1,$r2; my ($dx,$idx,@ret)=($r2 <=> $r1); $idx=($s < $f) ? -$s+$r1 : ($dx=-$dx,$s-$r1); while ( @ret <= abs($r2-$r1) ) { push @ret,$ary->[$idx]; $idx+=$dx; } return @ret; } # Excluding sub {} wrapper its 126 bytes. # 1 2 3 4 5 6 7 #123456789012345678901234567890123456789012345678901234567890123456789012345678 sub subrange_no_error { my($p,$q,$Y,$s,$f)=@_;my($d,$i,@r)=($q<=>$p);$i=($s<$f)?-$s+$p:($d=-$d,$s-$p); push(@r,$Y->[$i]),$i+=$d while@r<=abs($q-$p);@r; } #180 bytes (counting newline used as mandatory whitespace as one char) sub subrange_golf_error { my($p,$q,$Y,$s,$f)=@_;my($d,$i,@r)=($q<=>$p);$i=($s<$f)?-$s+$p:($d=-$d,$s-$p); ($_<$s&&$_<$f||$_>$s&&$_>$f)&&die"Bad range!"for$p,$q;push(@r,$Y->[$i]),$i+=$d while@r<=abs($q-$p);@r; } # this is now just a wrapper to subrange. Its just for testing and interface # compatibility sub arrange { my $href=shift; my @ret= subrange_golf_error(@{$href->{subrange}},$href->{arr},@{$href->{range}}); $href->{ret}=\@ret; unless (defined wantarray) { my $idx=$href->{range}[0]; my $dx=$href->{range}[1] <=> $href->{range}[0]; print "Subrange @{$href->{subrange}} of Array [". join(", ", map{ my $r="$idx:$_"; $idx+=$dx; $r } @{$href->{arr}}) ."] is <@ret>\n"; } else{ return wantarray ? @ret : \@ret; } } foreach my $t ([5,8],[8,5],[6,5],[6,7],[5,6],[7,6],[1,2],[8,9]) { foreach my $r ([8,5],[5,8]) { eval { arrange({ arr => [qw(cero uno dos tres)], range => $r, subrange =>$t }); 1 } or warn "Test @$t failed on range @$r:\n$@"; } }