Here's the goal: make a function that takes any number of equal-length strings, and returns an array of strings, where each string is the concatenation of the Nth character in each string.
Sample input: qw( jeff john mary )
Sample output: qw( jjm eoa fhr fny )
Here are my attempts:
# 51 chars
sub s2a{@_=@_;reverse+map{join"",map+chop,@_}1..length$_[0]}
# 51 chars
sub s2a{@_=@_;map{join"",map+s/(.)//s&&$1,@_}1..length$_[0]}
# 48 chars
sub s2a{map{join"",map+s/(.)//s&&$1,@_=@_}1..length$_[0]}
# 47 chars
sub s2a{map{join"",map{s/(.)//s;$1}@_=@_}1..length$_[0]}
# 45 chars
sub s2a{map{join"",map{s/.//s;$&}@_=@_}1..length$_[0]}
japhy --
Perl and Regex Hacker
Re (tilly) 1: (Golf) Strings-to-Array
by tilly (Archbishop) on Mar 30, 2001 at 09:17 UTC
|
I had to rename the function, but I get 38. It would be
shorter, but I added 3 chars to make it run under 5.6,
and added 2 more for a bug fix. Plus the obligatory 5
for a private variable.
So if I was a careless lout, I could claim 28, but I am
not...
sub r {my$s;$s.=chop for@_=@_;$s.0?(&r,$s):()}
UPDATE
D'oh. MeowChow is right. I need the private variable. | [reply] [d/l] |
|
| [reply] |
|
tilly would you care to explain it as well at the risk of me producing this type of code on my next project?
Jorg
"Do or do not, there is no try" -- Yoda
| [reply] |
|
sub r {
my $s;
$s .= chop for @_ = @_;
$s . 0 ?
( &r , $s ) :
()
}
and now with better variable names, fewer implicit
variables, rewritten loops, that kind of thing:
sub recursive_s2a {
my $str_last;
foreach my $str (@_ = @_) {
$str_last .= chop($str);
}
if ($str_last . 0) {
return (recursive_s2a(@_) , $str_last );
}
else {
return;
}
}
And now you see that the function creates the last string
in the list to produce, tests whether that was the empty
string, if it was it returns nothing, if it wasn't it then
proceeds by recursion to generate the first strings, and
adds the string it produced to that list. | [reply] [d/l] [select] |
|
sub r {my$s;$s.=chop for@_;$s?(&r,$s):()}
#0 1 2 3 3
#123456789012345678901234567890123
# jeff,john,mary
# jjm,eoa,fhr,fny
on v5.6.1-AS628. and it worked fine.
I suppose I am missing something, but I dont see what. Why are you doing @_=@_ and $s.0?? Is this an issue for an earlier version of perl? As far as I understand these are redundant ops. When does $s.0 evalute in a boolean sense different to $s? And what is the point of assigning @_ to itself? I am confused. OTOH it does mean that you can claim 5 less chars, for a total of 33. :-) Or am I being a lout?
Yves
| [reply] [d/l] [select] |
|
In Perl 5.6.0 if you passed in literal strings, you got
an error about, "Modification of a read-only value
attempted". Recopying @_ fixed that.
And the time when $s and $s.0 are different in boolean
context is when $s is "0". So when you remove those two
characters, you get a bug.
UPDATE
An example that shows the bug:
print map "$_\n", r("0a1", "b0", "0");
| [reply] [d/l] |
|
|
|
Re: (Golf) Strings-to-Array
by tye (Sage) on Mar 29, 2001 at 02:34 UTC
|
If you allow me my favorite tool, then I can do it in 31 characters and I don't need to use the awful $& and I don't require that the strings be the same length:
use mapcar;
sub s2a{mapcar{join"",@_}map[/(.)/g],@_}
-
tye
(but my friends call me "Tye") | [reply] [d/l] |
Re: (Golf) Strings-to-Array
by MeowChow (Vicar) on Mar 30, 2001 at 07:42 UTC
|
# 33 chars
sub s2a{map{$l[-1+pos].=$&while/./g}@_;@l}
... or 38 chars, if you want to throw in my@l;
MeowChow
s aamecha.s a..a\u$&owag.print | [reply] [d/l] [select] |
|
Add 6 chars. 5 for my@l; and one for the s modifier on your regex. 39 looks like the score to beat.
japhy --
Perl and Regex Hacker
| [reply] |
Re: (Golf) Strings-to-Array
by MrNobo1024 (Hermit) on Mar 29, 2001 at 03:50 UTC
|
sub s2a{my@q;$d=0,map$q[$d++].=$_,/./sg for@_;@q}
| [reply] [d/l] |
|
Ooh, very nice. But it clobbers a global $d. Here's my remedy:
# 41 chars
sub s2a {my@q;map{my$d;map$q[$d++].=$_,/./sg}@_;@q}
It uses map() in void context, but who cares?
japhy --
Perl and Regex Hacker | [reply] [d/l] |
Re: (Golf) Strings-to-Array
by MeowChow (Vicar) on Mar 30, 2001 at 23:21 UTC
|
sub s2a {map{join'',@$_}@{+Math::Matrix::transpose[map[split''],@_]}}
| [reply] [d/l] |
|
|