ciphergoth: (Default)
Paul Crowley ([personal profile] ciphergoth) wrote2003-10-04 02:37 pm

Setback in the Perl wars

Some of you may remember I posted this a while back:
#!/usr/bin/perl -0777
sub Q{$s[($_[0]+=$_[1])%=@s]}sub S{@s[$x,$y]=@s[$y,$x]}@k=map
hex,pop=~/../g;S Q$y,$k[$x%@k]+Q$x,$_>0for@s=0..255;$x=$y=0;print
chr($_^Q S Q$y,Q$x,1)for unpack'C*',<>

Well I sent it to Adam Back, and he put it online. However, subsequent to that, he sent me another, substantially shorter implementation he and another contributor had done ages ago:
#!/usr/bin/perl -p
INIT{@k=pop=~/../g;$^C=map@s[$w++,$^C]=@s[$^C+=$_+hex$k[$w%@k],$w],@s=0..255}
s#\C#$&^chr$s[255&map{1..$_}@s[$^C,$x]=@s[++$x,$^C+=$s[$x%=@s]]]#eg

This works because the variable $^C is stored in a byte, so half the modular arithmetic is unnecessary. There's a whole bunch of other novel tricks in there, though. Applying these tricks to my version, I get
#!/usr/bin/perl -p
INIT{sub Q{$s[($_[0]+=pop)%=@s]}sub S{@s[$x,$y]=@s[$y,$x]}@k=pop=~/../g;$x+=!!S
Q$y,$_+hex$k[$x%@k]for@s=0..255;$x=$y=0}s/\C/$&^chr Q S Q$y,Q$x,1/eg

which is three characters longer than the version he sent me. Bah!

Can anyone figure out a way to save four characters from this?

Update:
#!/usr/bin/perl -p
INIT{sub Q{$s[($_[0]+=$_[1])%=256]}sub
S{@s[$y,$x++]=@s[$x,$y]}@k=pop=~/../g;S$y=map{S
Q$y,$_+hex$k[$x%@k]}@s=0..255}s/\C/$&^chr Q S Q$y,Q$x/eg

[identity profile] lproven.livejournal.com 2003-10-04 07:30 am (UTC)(link)
Any chance of a commented version? Tho' I'd almost certainly still not understand it...

[identity profile] ciphergoth.livejournal.com 2003-10-04 07:54 am (UTC)(link)
That would take way too long and go out of date.

It's not too hard to take these things apart by yourself, and can be fun and extend your Perl knowledge. Write a little program to test the correctness of an implementation against a standard implementation (as simple as "./my-version deadbeef < test_in | cmp - test_out"), then slowly apply transformations to the program that don't break it according to your tests. Start by adding lots of white space, then make deeper changes...

[identity profile] lproven.livejournal.com 2003-10-04 08:37 am (UTC)(link)
[Chuckle]

I didn't get far past basic array handling in Perl. When I discovered my examples didn't work because the notation is different when defining and accessing arrays, my already vastly over-stretched patience with the language snapped. It doesn't map onto the way I think at all.

I may have a bash (ha ha) at Python one of these days. From a preliminary look, it makes a lot more sense to me.

[identity profile] ciphergoth.livejournal.com 2003-10-05 02:08 pm (UTC)(link)
Python rocks. You can't do this sort of nonsense in it, which for the most part of course is a good thing.

[identity profile] pavlos.livejournal.com 2003-10-05 05:12 pm (UTC)(link)
What he said!

[identity profile] lproven.livejournal.com 2003-10-08 08:51 am (UTC)(link)
So many things to do, so little time. Personally, I'd love a decent open-source reimplementation of BBC BASIC...

Jareth is born

[identity profile] simm42.livejournal.com 2003-10-04 09:05 am (UTC)(link)
How about just cheating and trying

ln -s /usr/bin/perl /p

;)


If I get time I might have a play with it later - not awake enough right now to focus on it

Your reading habits

[identity profile] webcowgirl.livejournal.com 2003-10-16 02:50 pm (UTC)(link)
So, do you read Joel Spoelsky? He had an interesting article about handling unicode in PHP that for some reason I thought you might find interesting.