# 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                    |
`---------------------------------------------'

-------------- 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.
}

```