Self-reproducing Spiral
n/a
nforrett at wgz.com
Tue Jul 16 13:01:48 CDT 2002
On Mon, 15 Jul 2002, Tyler F. Creelan wrote:
> Can anyone explain how this (very awesome!) perl code works?
Ok, I think I've redeemed myself. ;-) See attached.
--
Nick
,--< Nick Forrette >--------------------------.
| e-mail: nforrett at wgz.org |
| www : http://www.drforehead.net/ |
`---------------------------------------------'
-------------- next part --------------
On Mon, 15 Jul 2002, Tyler F. Creelan wrote:
> Can anyone explain how this (very awesome!) perl code works?
>
> "This self-reproducing code prints a turning spiral filled with it's own
> code."
>
> #!/usr/bin/perl
> $_='
> $q ="\ 47"; wh
> ile ($ ;=
> $z += .5 ){
> %c= $r=0;$/ ="";whi le(2
> 0+ $z>($;+=.05)){$c{int$ _+ 2
> 6+ 2*($ r+= .0 2) *
> s in$ ;}{1 -$_
> +1 0+ int $r*c o s
> $ ;} =1for(0. .1) }$
> t =r ever se;$ /. =`
> c le ar `. " #!
> / usr /bi n/ pe
> rl \n\ $_ =$q \n" ;
> fo r$y (1..20){$c{$_} {
> $ y }? $ /.=chop$t :
> ($/ . =" \4
> 0") for(0. .53) ;
> $/. ="\n"}pri nt"$/$ q;
> s; ". chr(9 2)."s;;g;eval\n "}
Set $_ to be a rather large string of (poorly) formatted perl code.
> ';s;\s;;g;
# Remove all the whitespace from $_
> eval
Evaluate the whitespaceless $_.
Now if we remove the whitespace earlier, and strategicly add some back in to
clarify the ccdes intent, you get something like this...
$q = "\47" ;
while( $; = $z += .5) {
%c = $r= 0 ;
$/ = "" ;
while( 20 + $z > ($; += .05)) {
$c{int $_ + 26 + 2 * ($r += .02) * sin $;}{1 - $_ + 10 + int $r * cos $;} = 1 for(0 .. 1)
}
$t = reverse ;
$/ . = `clear` . "#!/usr/bin/perl\n\$_=$q\n" ;
for $y (1 .. 20) {
$c{$_}{$y} ? $/ .= chop $t : ($/ .= "\40") for(0 .. 53);
$/ .= "\n"
}
print "$/$q;s;" . chr(92) . "s;;g;eval\n"
}
With some added comments, and rewriting the inner while loop, you get
the following.
# Set $q to ascii octal 47, or the single quote
$q = "\47" ;
# Increment $; and $z by .5. It appears that $; is used to obfusticate things,
# as is $/ (in other words, they could have used normal variables)
while( $; = $z += .5) {
%c = $r = 0 ;
$/ = "" ;
# This loop actually constructs the spiral. The hash %c is used to store the
# legal locations that characters can be stored in the final result. The
# first key is the Y screen coordinate, the second hash key is the X
# coordinate. If a character is allowed at that point on the screen, the
# appropriate hash entry is set to 1.
while( 20 + $z > ($; += .05)) {
for (0 .. 1) {
# Formula for spiral of archimedes:
# x = t cos t
# y = t sin t
# where x and y are rectangular coordinates, and t is time.
# in this case, $c{Y-coord}{X-coord}, and $; represents time
# the rest seems to be fudge factor
$c{int $_ + 26 + 2 * ($r += .02) * sin $;}{1 - $_ + 10 + int $r * cos $;} = 1 ;
}
}
# Here is where the magic happens. Remember that $_ was s/\s//g -ified, and
# then evaled. Now $_ still contains the whitespace stripped code. However,
# the code that was whitepsace stripped was capable of reconstructing the
# original spiral (stored in %c). So $t ends up with the reverse of the body
# code
$t = reverse ;
# This clears the screen and represents the first two lines of replicated
# code in each iteration of the outer while loop
$/ . = `clear` . "#!/usr/bin/perl\n\$_=$q\n" ;
# Loop over the X/Y coordinates
for $y (1 .. 20) {
for (0 .. 53)
{
# if the spiral calculator determined that there should be a character
# here, chop a character off the end and append it to $/ (which contains
# the screen clearing, and first two lines of code already. Remember
# that $t is the code backwards, so this will be the first character of
# the code forwards. If there is not supposed to be a character here,
# then put a space character in that location.
$c{$_}{$y} ? $/ .= chop $t : ($/ .= "\40") ;
}
$/ .= "\n"
}
# Here we print out the first two lines, and the spiralized body code, then
# the last s;\s;; and eval.
print "$/$q;s;" . chr(92) . "s;;g;eval\n"
# The outer loop is purely for effect. It has the net effect of making the
# spiral appear to rotate. However, I found that you have to have a suitable
# slow machine to actually see the spiraling. Strictly speaking, it is not
# needed.
}
More information about the Pdx-pm-list
mailing list