Re: Is Perl less compact than Ruby? (Kind of competition)
by cLive ;-) (Prior) on Feb 18, 2002 at 21:12 UTC
|
Well, since it doesn't work under strict, you can safely drop:
$n=0;
that's another 5 chars.
Also, put pop@n in a sub at the beginning:
sub p{pop@n}
then replace:
pop@n => p
throughout. another 20 chars saved.
sub w{push@n,$_[0]}sub p{pop@n}map{push@L,@C+0;push@C,split//,lc}<>;wh
+ile($n<@C){$_=$C[$n++];if(/n/){$0=0;/-/ or$0=$_+$0*7while($_=index"ht
+aoinse",$C[$n++])<7;w$0}if(/t/){$_=p@n;$_?$n=$L[$_-1]:last if p@n}/a/
+&&push@n,1+grep$n>$_,@L;if(/h/){$_=p@n;$n[$#n-abs];$_>0&&splice@n,@n-
+2-$_,1}/o/&&print+chr(p@n);/s/&w-(p@n)+p@n;$0=p@n,$_=p@n,w(int$_/$0),
+$_%$0if/e/;w($_=getc)?ord:-1if/i/}
cLive ;-)
Update - d'oh, yep, another 16 chars saved by changing p@n to p (updated above) - that means we can also save another 10 chars by whacking push@n,'whatever' into a sub.
What's that now? 379 chars?
--
seek(JOB,$$LA,0);
| [reply] [d/l] [select] |
|
|
Excellent!
pop@n => p@n
or simply to 'p', yes?
| |
|
|
sub p{pop@n}sub v{push@n,@_}map{push@L,@C+0;push@C,lc=~/./g}<>;while($
+n<@C){$_=
$C[$n++];if(/n/){$0=0;/-/ or$0=$_+$0*7while($_=index"htaoinse",$C[$n++
+])<7;v$0}
if(/t/){$_=p;$_?$n=$L[$_-1]:last if p}/a/&&v 1+grep$n>$_,@L;if(/h/){$_
+=p;v$n[
$#n-abs];$_>0&&splice@n,@n-2-$_,1}/o/&&print+chr(p);/s/&&v-(p)+p;$0=p,
+$_=p,v
int$_/$0,$_%$0if/e/;v(($_=getc)?ord:-1)if/i/}
Thank you!!! What's next? | |
|
|
|
|
|
|
|
Re: Is Perl less compact than Ruby? (Kind of competition)
by tadman (Prior) on Feb 18, 2002 at 19:27 UTC
|
Before pulling apart the interpreter, you can at least shave
a character off the preamble using the old m// trick:
# Formerly:
split//,lc
# Revised:
lc=~m/./g
# Revised revision [mtve]:
lc=~/./g
Chalk one up for Perl!
Update: mtve points out the obvious. D'oh! | [reply] [d/l] |
|
|
Thanks! Worked even without m, is it ok?
| |
Re: Is Perl less compact than Ruby? (Kind of competition)
by grinder (Bishop) on Feb 18, 2002 at 22:40 UTC
|
By folding the suggestions encountered so far, and adding in some of my own, I was able to bring the total down to 342 characters. Big gains can be made by observing that $foo[-2] refers to indices at the end of an array. That happens twice in this script.
In the part where the code pops to $_ and $0, it's cheaper to just call pop @n directly. This was the case with pop@n, and I guess it will still hold with p.
sub w as written contains a bug. Sometimes you push more than one element on. But that's okay, @_ is a win over $_[0].
I tried changing expr if cond to cond&&expr but that didn't do anything.
map{push@L,@C+0;push@C,lc=~/./g}<>;sub p{pop@n}sub w{push@n,@_}while($
+n<@C){$_=
$C[$n++];if(/n/){$0=0;/-/ or$0=$_+$0*7while($_=index"htaoinse",$C[$n++
+])<7;w$0}
if(/t/){$_=p;$_?$n=$L[$_-1]:last if p}/a/&&w 1+grep{$n>$_}@L;if(/h/){$
+_=p;w$n[-
abs$_];$_>0&&splice@n,-1-$_,1}/o/&&print chr p;/s/&&w-p()+p;/e/&&w int
+ p()/p,p%
p;w($_=getc)?ord:-1if/i/}
Note that changing /s/&&v-(p)+p to
/s/&&v+p-p breaks the interpreter. Or at least,
the hello.eta program no longer runs correctly, which was the extent of my testing. The interpreter is quite slow.
print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u' | [reply] [d/l] [select] |
|
|
but a few bugs exists. p has side effect of modifying @n, so for example in /e/ part you must call it only twice not four times. in last expression correct logic is w+($_=getc)?ord:-1if/i/
| |
Good and bad news
by locked_user mtve (Deacon) on Feb 19, 2002 at 08:04 UTC
|
Good news is that by common efforts we clear first hurdle, 357 bytes.
Bad news is that Ruby is also don't stand still, and as you can see here it's now four lines and 306 bytes long!
n=[];p=$<.readlines;$==f=l=c=0;loop{p[l].gsub(/(a)|(i)|(n)|(o)|(h)|(e)
+|(s)|t/){
f>0?$6?n<<c&&c=f=0:c="htaoins".index($&)+c*7: $1?n<<l+2: $2?n<<STDIN.g
+etc: $3?f=
1:(a=n.pop;$4?$><<a.chr: $5?n<<n[-1-a.abs]&&a>0&&n.slice!(-2-a):(b=n.p
+op;$6?n<<
b/a&&n<<b%a: $7?n<<b-a: b!=0&&(l=a-2;break)))};p[l+=1]&&l>=0||break}
How do you like this intrigue? | |
|
|
map{push@L,@C+0;push@C,lc=~/./g}<>;sub p{pop@n}sub w{push@n,@_}while($
+n<@C){$_=
$C[$n++];if(/h/){$_=p;w$n[-1-abs];$_>0&&splice@n,-2-$_,1}if(/n/){w 0;/
+-/||w$_+7
*p while($_=index"htaoinse",$C[$n++])<7}$0=p,$_=p,w int$_/$0,$_%$0if/e
+/;if(/t/)
{$_=p;$_?$n=$L[$_-1]:last if p}/a/?w 1+grep$n>$_,@L:/o/?print chr p:/s
+/?w-(p)+p
:/i/?w+($_=getc)?ord:-1:0}
Beg you for another 26 bytes, is it possible?
| |
|
|
map{push@L,@C+0;push@C,lc=~/./g}<>;sub p{pop@n}sub w{push@n,@_}while($
+n<@C){$_=
$C[$n++];if(/h/){$_=p;w$n[-1-abs];$_>0&&splice@n,-2-$_,1}if(/n/){w 0;/
+-/||w$_+7
*p while($_=index"htaoinse",$C[$n++])<7}$0=p,$_=p,w int$_/$0,$_%$0if/e
+/;if(/t/)
{$_=p;$_?$n=$L[$_-1]:last if p}/a/?w 1+grep$n>$_,@L:/o/?print chr p:/s
+/?w-(p)+p
:/i/&&w($_=getc)?ord:-1}
We can s/last if p/p&&last/ and that brings it own to 338 bytes:
map{push@L,@C+0;push@C,lc=~/./g}<>;sub p{pop@n}sub w{push@n,@_}while($
+n<@C){$_=
$C[$n++];if(/h/){$_=p;w$n[-1-abs];$_>0&&splice@n,-2-$_,1}if(/n/){w 0;/
+-/||w$_+7
*p while($_=index"htaoinse",$C[$n++])<7}$0=p,$_=p,w int$_/$0,$_%$0if/e
+/;if(/t/)
{$_=p;$_?$n=$L[$_-1]:p&&last}/a/?w 1+grep$n>$_,@L:/o/?print chr p:/s/?
+w-(p)+p:
/i/&&w($_=getc)?ord:-1}
But wait, there's more! change $0=p,$_=p,w int$_/$0,$_%$0 to w int($_=p)/($0=p),$_%$0}
Which gives 337 (I think) bytes:
map{push@L,@C+0;push@C,lc=~/./g}<>;sub p{pop@n}sub w{push@n,@_}while($
+n<@C){$_=
$C[$n++];if(/h/){$_=p;w$n[-1-abs];$_>0&&splice@n,-2-$_,1}if(/n/){w 0;/
+-/||w$_+7
*p while($_=index"htaoinse",$C[$n++])<7}w int($_=p)/($0=p),$_%$0if/e/;
+if(/t/)
{$_=p;$_?$n=$L[$_-1]:p&&last}/a/?w 1+grep$n>$_,@L:/o/?print chr p:/s/?
+w-(p)+p:
/i/&&w($_=getc)?ord:-1}
A ternary operator can be replaced by a && and the plus in w+($_=getc)?ord:-1 trick is not needed, it works without (or, at least, hello.eta still outputs correctly).
I have an idea it must be possible to replace the w$_+7*p while($_=index"htaoinse",$C[$n++])<7 section with a redo and/or a pos, but it is so
difficult to understand what the program does I am
beginning to wonder whether it wouldn't be easier to look
at the instruction set and come up with another angle of attack. For instance, it would be nice to be able to do away with the @L array as well. Replace @C and @L by a hash that is keyed on byte offset and the value is the byte.
print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u' | [reply] [d/l] [select] |
|
|
Re: Is Perl less compact than Ruby? (Kind of competition)
by dragonchild (Archbishop) on Feb 19, 2002 at 17:14 UTC
|
map{push@L,@C+0;push@C,lc=~/./g}<>;sub p{$_=pop@n}sub w{push@n,@_}whil
+e($n<@C){$_=$C[$n++];if(/h/){p;w$n[-1-abs];$_>0&&splice@n,-2-$_,1}if(
+/n/){w 0;$b<0||w$b+7*p while($b=index"htaoinse",$C[$n++])<7}$0=p,p,w
+int$_/$0,$_%$0if/e/;if(/t/){$a=p;$a?$n=$L[$a-1]:last if p}/a/?w 1+gre
+p$n>$_,@L:/o/?print chr p:/s/?w-(p)+p:/i/&&w+($_=getc)?ord:-1}
The big change was sub p{$_=pop@n} and the subsequent fall-out. *pants*\
Update: To 336...
if(/t/){$a=r;$a?$n=$L[$a-1]:last if r}
---
$a=r,r&&($a?$n=$L[$a-1]:last)if/t/;
------ We are the carpenters and bricklayers of the Information Age. Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement. | [reply] [d/l] [select] |
|
|
Another update, bringing to 331. Though I'm not sure the change is legal, it runs the Tic-Tac-Toe program.
map{push@L,push@C,lc=~/./g}<>;sub p{$_=pop@n}sub w{push@n,@_}while($n<
+@C){$_=$C[$n++];if(/h/){p;w$n[-1-abs];$_>0&&splice@n,-2-$_,1}if(/n/){
+w 0;$b<0||w$b+7*p while($b=index"htaoinse",$C[$n++])<7}$0=p,p,w int$_
+/$0,$_%$0if/e/;$a=p,p&&($a?$n=$L[$a-2]:last)if/t/;/a/?w 2+grep$n>$_,@
+L:/o/?print chr p:/s/?w-(p)+p:/i/&&w+($_=getc)?ord:-1}
The change was to functionally remove the 0 at the beginning of @L. Adjusting the subscripts used to access @L seems to result in an acceptable performance.
------ We are the carpenters and bricklayers of the Information Age. Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement. | [reply] [d/l] |
|
|
One thing people often forget is that push@L,values is a semantically equivalent (modulo being faster) to @L=@L,values - a saving of one character per push, or three characters in the above, bringing you down to 328.
| [reply] |
|
|
|
|
|
|
Excellent tweak with push!
map{push@L,push@C,lc=~/./g}0,<>; should fix this. It's nice question but I believe impossibility to jump on first line is some violation of language. It's my fault of incorrect target setting.
| |
|
|
| |
Re: Is Perl less compact than Ruby? (Kind of competition)
by jynx (Priest) on Feb 19, 2002 at 19:03 UTC
|
/i/&&w+($_=getc)?ord:-1
# goes to:
/i/&&w(ord getc|-1)
jynx
update: take out the parens on that up there: /i/&&w ord getc|-1
for another 1 char savings... | [reply] [d/l] [select] |
|
|
/i/&& w ord getc||-1
You forgot a '|'. That brings us to 306. :-)
------ We are the carpenters and bricklayers of the Information Age. Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement. | [reply] [d/l] |
|
|
my testing has been limited,
i've only been using hello.eta and hello2.eta, but using | seems to be equivalent to || there. i tested both ways and they seem to work okay on the two hello programs. did your tests come out differently? if so, which programs should i be testing with (that is, which are more indicative of a real ETA program?)
As for the tic-tac-toe program, no matter which of the recent incarnations of the perl program i try, it seems to hang after i've given it input. does it just take a really long time or is it still running?
jynx
| [reply] [d/l] [select] |
|
|
|
|
Re: Is Perl less compact than Ruby? (Kind of competition)
by blakem (Monsignor) on Feb 18, 2002 at 19:35 UTC
|
Oops... nothing to see here.
While I don't have time to actually play this round of golf, the perl version can definately be shortened. For instance, the while clause in the first line jumps out as being longer than necessary:
while($n<@C){$_=$C[$n++]};
Becomes:
$_=$C[$n++]while$n<@C;
Shaving 4 chars off of the total.....
-Blake
| [reply] [d/l] [select] |
|
|
| |
Hooray!
by locked_user mtve (Deacon) on Feb 20, 2002 at 21:18 UTC
|
I must say it again, WE WIN with 290 bytes:
sub p{$_=pop@n}sub w{push@n,@_}$/=$T;$_=uc<>;s#.#+{qw(E 7$0=p;p;w+int$
+_/$0,$_%$0
H 0p;w$n[-1-abs];$_>0&&splice@n,-2-$_,1 I 4w+($_=getc)?ord:-1 A 2w$L+1
+ N 5w$N++
S 6w-(p)+p O 3print+chr(p) T 1$t=p;p&&goto"L$t")}->{$&}=~/./&&"\$N?$&>
+6?\$N=0:".
"w $&+7*p:do{$'};"#eg;s/^/L${\++$i}:\$L=$i;/mg;eval
| |
Latest results
by locked_user mtve (Deacon) on Feb 20, 2002 at 11:26 UTC
|
Thanks to tadman, cLive ;-) , blakem, dragonchild, grinder, Matts, jynx and PerlMonks.org, Perl version in now officially 333 bytes (or 327 bytes with some cheating), while Ruby is still 306 bytes.
map{push@L,push@C,lc=~/./g}0,<>;sub p{$_=pop@n}sub w{push@n,@_}while($
+n<@C){$_=$
C[$n++];if(/h/){p;w$n[-1-abs];$_>0&&splice@n,-2-$_,1}if(/n/){w 0;$b<0|
+|w$b+7*p
while($b=index"htaoinse",$C[$n++])<7}$0=p,p,w int$_/$0,$_%$0if/e/;$a=p
+,p&&($a?$n
=$L[$a-1]:last)if/t/;/a/?w 1+grep$n>$_,@L:/o/?print chr p:/s/?w-(p)+p:
+/i/&&w+($_
=getc)?ord:-1}
| |
|
|
sub p{$_=pop@n}
sub w{push@n,@_}
%D=(
H=>'0p;w$n[-1-abs];$_>0&&splice@n,-2-$_,1',
T=>'1$t=p;p&&goto"L$t"',
A=>'2w$L+1',
O=>'3print chr p',
I=>'4w+($_=getc)?ord:-1',
N=>'5w$N++',
S=>'6w-(p)+p',
E=>'7$0=p;p;w int$_/$0,$_%$0'
);
$/=\-1;$_=uc<>;
s#.#$D{$&}=~/(.)(.*)$/&&"\$N?$1>6?\$N=0:w $1+7*p:do{$2};"#eg;
s/^/$i++,"L$i:\$L=$i;"/emg;
eval;
L0:
| |
|
|
Here's some more, then. It also adds the (missing?) newline to the end of each command.
sub p{$_=pop@n}
sub w{push@n,@_}
$/=$T;$_=uc<>;
s#.#+{qw(
H 0p;w$n[-1-abs];$_>0&&splice@n,-2-$_,1
T 1$t=p;p&&goto"L$t"
A 2w$L+1
O 3print+chr+p
I 4w+($_=getc)?ord:-1
N 5w$N++
S 6w-(p)+p
E 7$0=p;p;w+int$_/$0,$_%$0
)}->{$&}=~/./&&"\$N?$&>6?\$N=0:w $&+7*p:do{$'};\n"#eg;
s/^/L${\++$i}:\$L=$i;/mg;
eval;
L0:
_____________________________________________________
Jeff[japhy]Pinyan:
Perl,
regex,
and perl
hacker, who'd like a (from-home) job
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??; | [reply] [d/l] |
|
|
|
|
|
|
|
|
|
|
Nicely done! Shave three with I=>'4w ord getc||-1',.
------ We are the carpenters and bricklayers of the Information Age. Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.
| [reply] [d/l] |
|
|