Skip to content

Instantly share code, notes, and snippets.

@jedp
Last active December 11, 2015 05:29
Show Gist options
  • Save jedp/4552786 to your computer and use it in GitHub Desktop.
Save jedp/4552786 to your computer and use it in GitHub Desktop.
Jed's (was) another Perl Hacker

Thanks to the Way Back Machine, I found the perl sigs that I wrote while avoiding doing work on my Latin PhD in the years 2000 and 2001 AD.

I have no idea if these still work with anything other than Perl 4 or whatever it was at the time. I also have no idea how to write perl anymore. But I was addicted to playing games with it at the time. You could write beautiful numerical and lexical puzzles and poems with that crazy language. It was so much fun to explore with. And the Perl Journal was awesome.

1

':2F5D)W,@86YO=&AE<B!P97)L(&AA8VME<@H'=~/.*/&& print unpack ("u",$&);

Starting off simple here. Prints “Jed's another Perl hacker” using a wimpy little uuencoded string.

2

grep(do{for(ord){$o+=$_&7;grep(vec($j,+$o++,1)=1,5..($_>>3||print"$j\n"))}},
(split(//,"))*))2+29*2:.*4:1A1+9,1))2*:..)))2*:31.-1)4131)1))2*:\7Glug!")));

Prints "Jed's another Perl hacker". This is almost entirely a direct adaptation of one by Larry Wall, only I changed the encoded text. (See #5 and #6 below for more about how this works.)

His encoding scheme works in eight bit chunks, which allows for the really elegant 5..($>>3||print) statement and the $_ & 7 mask. I had to give this up in my six bit version below (conveniently numbered #6).

3

@@=split(m@\S\n?@,<<';-)');vec($_,$-+=length(shift@@),1)=1while@@;print"$_\n";
 :-)  :-)   :-)  :-)  :-)   :-) :-)    :-)   :-) :-)  :-) :-) :-)   :-)   :-)
 :-)   :-) :-) :-)       :-)   :-)     :-) :-)   :-) :-) :-)  :-) :-)  :-) :-)
 :-) :-)  :-) :-)    :-)  :-) :-) :-)     :-)  :-) :-)  :-)  :-)   :-) :-)
   :-)   :-) :-) :-)       :-)       :-)  :-)  :-)  :-)   :-) :-)   :-)   :-)
 :-) :-)    :-) :-)  :-) :-)       :-)      :-)  :-) :-)  :-)     :-) :-)  :-)
 :-)    :-) :-)  :-) :-)  :-)  :-) :-)  :-)  :-)   :-) :-)   :-)   :-) :-) :-)
;-)

Prints "Jed's another Perl hacker". This is an adaptation of a really cute one by Randall Schwartz. Here, we generate a string of text bit by bit. The spaces between the smileys tell us how far to move over to set the next bit. (In other words, the smileys are 1s, and the spaces are 0s.)

4

$/="";$_=<DATA>;s=.*?([+-]\d+)=pack('C',$-+\=$1)=seg&&print;__END__
+74 G +27 L  -1 U -61 G +76 -83 I +65 S +13+1 T +5 H -12 E -3
    S +13 O -82 N +48+21+13 O -6 F -76 +72 -7 Z +2 E +08 U -6 S +13

Prints "Jed's another Perl hacker". The last two lines are slurped as DATA. The digits and sign values, when added to a running sum, yield the ascii values of the text. The letters and spaces are just noise.

5

grep(do{for(ord){$S+=$_&7;grep(vec($s,+$S++,1)=1,5..$_>>3)}},
(split(//,$k,($k=unpack("b*","Jed's another Perl hacker"))=~s
/(0+)(1+)/chr(32+(8*length$2)+length$1)/eg))) or print"$s\n";

Prints "Jed's another Perl hacker". This is basically a simplified version of #2 and #6 that both packs the message into a bit string, encodes that bit string as a stream of characters, and then immediately decodes the character stream and unpacks the bits using the algorithm detailed in #6 (that's what's going on in the regex).

6

grep(do{for(ord){(!$_&&print"$s\n")||(($O+=(($_-1)%6+1)and 
grep(vec($s,$O++,1)=1,1..int(($_-6*6-1)/6))))}},(split(//, 
"++,++2-27,280,481=1-7.1++2,800+++2,8310/1+4131+1++2,80\0.  What!?")));

This one is by far my favorite. It prints "Jed's another Perl hacker". This is inspired by the Larry Wall JAPH (on which #2 above is based), but I've moved a lot of things around. Also, I've moved and condensed his original encoding table, since I didn't need all the bit combinations it could represent. The result lets me have the encoded text in line 3 (which is cool because it looks like its supposed to be arithmetic) as well as lots of 6s everywhere. The word in the margin is noise, since everything after the null character in the string is ignored.

Here's an explanation of the idea. The program assembles the bit vector for the ascii representation of "Jed's another Perl hacker", and then decodes the bitstring and prints the ascii text. Bit by bit, it forms the string $s with the vec function. This is done by by installing chunks that have one or more initial 0s and one or more final 1s. For example, if we were to encode the bit string 010001110110011, we would use these chunks: 01, 000111, 011, and 0011. Each character in the last line represents one such chunk. For example, + is 01, , is 001, and so on. Given the (accidental) nature of the bit patterns of the ascii data to be encoded, we only need up to six 0s and four 1s. It is a nice coincidence that we can use only the numerical characters in the ascii set to represent this data, according to the following table:

                                  1 
                                1 1
                              1 1 1
                            1 1 1 1
      
                         0  + 1 7 =
                        00  , 2 8
                       000  - 3 9
                      0000  . 4 :
                     00000  / 5 ;
                    000000  0 6 <

For example, the character ; represents the bitstring 00000111.

Now it is a simple matter of decoding the 0s and 1s. In a nutshell, the first grep will print the constructed string when the split function returns the null character to it. Until then, it sets $O to be the number of preceding 0s (according to the modulo arithmetic). In the nested grep, the vec function moves over that many spaces and one more. This is necessary in the initial case, since we have to get past the previous bit position. It is also handy, because it allows us to step over one space with each iteration of the grep. Each time vec is called, it sets the next bit to 1. The grep uses integer division to figure out how many 1s to add. Here, the number 36 is useful, which I chose to express as 6 * 6, since the number of 6s is appealing. In sum, the outer grep is responsible for setting the number of 0s, and the inner grep for setting the number of 1s.

7

($qq=qq[-7-00+18+15-00-19+9+79+16+3-8+13-78-36-4+17+76-67+3-15-6-9+38+82])=~
s/[+-]\d+/pack(qq$\103$,(ord(substr("Quae te dementia cepit? ",$i++,1)))+$&)
/eg and print $qq.qq.\012.; 

Prints "Just another Perl hacker", which is encrypted, as it were, as the phrase in the second line, according to the one-time-pad in the first line. Kind of lame, and it's not as pretty as the others, but I like the phrase and the stammering Qs all over the place :-) ("Quae te dementia cepit," from Vergil: "What madness has seized you?")

8

use Curses;$s="Jed's another Perl hacker ";initscr;for(;;){$f=($f+10)%360;grep
(do{$g=($f-$_*10)*atan2(1,1)*4/180;for(($m,$n)=qw(cos sin)){s/.*/"11+int(12*$&
($g))"/ee}addstr($m,$n+27,(substr$s,$_,1))},0..(length $s)-1);refresh;sleep 1}

This one makes the text string "Jed's another Perl hacker" trail in a circle around the middle of your screen. More specifically, it puts each character on the end of a vector 11 cell widths from the midpoint. It rotates each vector 10 degrees around the origin with each iteration of the for loop. The relative position of each character is determined in the grep statement, as are the values of $m and $n (the coordinates of each letter). These two variables are assigned by means of a for loop that does a regex replace around cos and sin, and double-evaluates the replacement text. To convert degrees to radians, it computes pi with the atan2 (1, 1) * 4 trick.

This is all basic trig. $m, representing the column of a cell, is computed as radius * cos theta; $n, the row, is radius * sin theta. The angle theta ($g) is incremented by phi ($f), which is set at 10 degrees per iteration. Each letter in the string has a theta that is ten degrees less than the one before it (that's the $f - $_ * 10 part). This keeps each letter in its own cell. The last letter is just a blank space which serves to erase the last character in the string printed on the previous pass.

Sorry about the cursor block: I can't remember how to get rid of it. :-) Can anyone help me out?

9

use Curses;initscr;for(;;){$f=($f+10)%360;clear;grep(do{$i=$
_;for(($m,$n)=qw(cos sin)){s|.*|"int(($i-13)*$&($f*(atan2(1,
1)*4)/180))"|ee}addstr$m+11,$n+31,substr$s,$i,1},0..(length(
$s=unpack(qq'u',':2F5D)W,@86YO=&AE<B!P97)L(&AA8VME<@')))-1);    
CONFUSING: study each word & character; sleep 1 and refresh}

This little number takes the string "Jed's another Perl hacker", which is pointlessly uuencoded in the fourth line, and twirls it around a midpoint in the center of the screen like a pinwheel. It's pretty similar to the last one computationally, though more condensed in some respects (e.g., the computation of $f (which stands for phi, or change in the angle theta) is done for each character in the grep.) Some of the words in the last line do nothing, but they make for nice reading. I know this one's pushing the length limit for a sig, but I really like it formatted this way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment