I was poking around cpan the other day and I found this lovely function named "array_pad", whose stated purpose was to take a size, a scalar and a list, and to produce a padded list using the new size. If the size is possitive, the scalar is replicated on the right side of the list (that is, pushed) and if the size is negative, the scalar is added on the left hand side of the array (that is, pushed). So in other words, you take a size, a scalar and a list and produce a new list that is padded with the appropiate number of scalars. If size is smaller than the list, then nothing happens and you may return the original array.
The actual implementation of the function is thus:
#Returns a copy of the input padded to size specified by pad_size with
+ value pad_value.
#If pad_size is positive then the array is padded on the right, if it'
+s negative then on the left.
#If the absolute value of pad_size is less than or equal to the length
+ of the input then no padding takes place.
#int pad_size, mixed pad_value, array input
sub array_pad{
my($pad_size, $pad_value, @array) = @_;
#this is just to get the absolute value of the pad_size
my $temp = $pad_size;
if($pad_size < 0){
$temp = $temp * -1;
}#if
#first let's see if the pad_size is less than or equal to the arra
+y size, return 0 no padding
my $input_size = @array;
if($temp <= $input_size){
return 0;
}#if
#since it didn't return 0, time to pad
#if the pad_size is < 0, pad on the left, else the right
if($pad_size < 0){
my @retval;
$temp = $temp - $input_size;
for(my $i=0;$i<$temp;$i++){
unshift(@array, $pad_value);
}#for
return @array;
}#if
else{
$temp = $pad_size - $input_size;
for(my $i=0;$i<$temp;$i++){
push(@array, $pad_value);
}#for
return @array;
}#else
}#array_pad
And of course I immediately thought "How could I golf this?" and after a couple of rounds on IRC I produced this:
sub p{my($i,$z,@f)=@_;abs$i>@f&&$i<0?@f=(($z) x abs($i+@f),@f):(@f[@f.
+.$i-1]=($z)x($i-@f));@f}
Which is really fairly long, and I know there are better solutions, because other people wrote some =].
This is the test suite used to test entries:
use Test::More tests => 4;
my @x = 1 .. 5;
is_deeply([p( 3, 'x', @x)], [ @x ]);
is_deeply([p(-3, 'x', @x)], [ @x ]);
is_deeply([p( 7, 'x', @x)], [ @x, 'x', 'x' ]);
is_deeply([p(-7, 'x', @x)], [ 'x', 'x', @x ]);
Where p() is the function you've written. So can anyone come up with something shorter than mine (you certainly should), or shorter than 60 chars (which is the shortest one I've seen)?
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.