Daniel Martin
8/8/2006 3:41:00 PM
Michael Ulm <michael.ulm@isis-papyrus.com> writes:
> Using the idea by Daniel Martin on your site, I managed to come up with a
> 232 byte solution:
>
> c,$k=STDIN.read.split'!'
> eval "d,a=[],0;"+c.unpack("C*").map{|i|
> {10,"",?+,"y+",?-,"y-",?[,"while y*>0 do",?],"end",?.,"print y*.chr",
> ?,,"d[a]=$k.slice!(0) or exit"}[i]||"a+=#{i-61}"
> }.join(";").gsub(/y(.)/,'(d[a]=(d[a]||0)\11&255)')
I've found I can do even better by switching d to a huge (32K) string
of \0s, which lets you dispense with the &255 bit. I also went back
to building the new script in a separate variable, which let me
replace .unpack("C*").map with .each_byte
I like your use of gsub and wish I could take advantage of that too,
but trying to ends up with a net expansion of my current 214 byte
version:
c,$k=STDIN.read.split'!'
j=%w[d="\0"*8**5 a=0]
c.each_byte{|i|j<<{?<,"a-=1",?>,"a+=1",?+,"d[a]+=1",
?-,"d[a]-=1",?[,"while d[a]>0 do",?],"end",
?.,"print d[a,1]",?,,"d[a]=$k.slice!(0)||exit"}[i]||''}
eval j.join("
")
As with yours, you get to 214 bytes by joining the lines that make up
the hash literal.