#!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'merz.ANSWER' <<'END_OF_FILE' XThomas Merz writes: X XWhat is it? An excerpt from a debugging session? PostScript-beginners Xfirst trial-and-exec? No! This is the smallest piece of Xselfreproducing code (that I know of). It elegantly shows the Xinterchangeability of code and data in the PostScript language. Except Xfor minor changes it is fully portable (on some interpreters you have Xto change the blanks before and after brackets and curly braces). X XHow does it work? The procedure in the first line is used as data Xwhich is output to %stdout. Then, the procedure is used as code which Xis executed. What does this code do? It outputs the second line and Xflushes the output channel. That's it! X Xthe {(pstack exec) = flush} goes entirely to the stack as a procedure. Xthe pstack prints it. And then the "exec" executes the procedure, Xprinting "pstack exec". X XAs you know, selfreproducing code is one of the key issues in the Xsurvey of computer viruses. While I am not going to spread PostScript Xviruses among printers and other devices, I think it's a sort of Xintellectual challenge and training of programming skills to develop Xselfreproducing code. END_OF_FILE if test 1116 -ne `wc -c <'merz.ANSWER'`; then echo shar: \"'merz.ANSWER'\" unpacked with wrong size! fi # end of 'merz.ANSWER' fi if test -f 'merz.HINT' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'merz.HINT'\" else echo shar: Extracting \"'merz.HINT'\" \(147 characters\) sed "s/^X//" >'merz.HINT' <<'END_OF_FILE' Xmerz.ps, by Thomas Merz, c/o R. Oldenbourg Verlag, Postfach 80 13 60, X8000 Munchen 80, GERMANY, won an honorable mention. X XRun this interactively. END_OF_FILE if test 147 -ne `wc -c <'merz.HINT'`; then echo shar: \"'merz.HINT'\" unpacked with wrong size! fi # end of 'merz.HINT' fi if test -f 'merz.ps' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'merz.ps'\" else echo shar: Extracting \"'merz.ps'\" \(36 characters\) sed "s/^X//" >'merz.ps' <<'END_OF_FILE' X{(pstack exec) = flush} Xpstack exec END_OF_FILE if test 36 -ne `wc -c <'merz.ps'`; then echo shar: \"'merz.ps'\" unpacked with wrong size! fi # end of 'merz.ps' fi if test -f 'mm.ANSWER' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mm.ANSWER'\" else echo shar: Extracting \"'mm.ANSWER'\" \(3984 characters\) sed "s/^X//" >'mm.ANSWER' <<'END_OF_FILE' XAllen writes: X XThis program plays Master Mind. Start it by typing: X X please begin game X XEnter moves by typing: X X (aaaa) guess X XGuesses should be strings of length four and contain the letters a-g. XThese parameters can be changed (see notes below). I have spent may Xhours- uh- debugging this program. Yeah, I wasn't playing games, Xhonest! X XI was discussing the contest with someone here and we came to the Xinteractive category. He asked what that meant and what good an Xinteractive PostScript program could be. I jokingly said that I should Xwrite a chess program. X XWell, I've never much cared for chess and the size and memory Xlimitations might be restrictive, so I fooled with tic-tac-toe and then Xsettled on Master Mind. X XThe program took a while to put together because of my refusal to use Xan excessive amount of dictionary space or to leave anything on the Xstack between turns. X XAs a result, most of the obfuscation is procedural. The large number Xof stack operations can be quite dizzying if you don't keep good Xcount. It's easier now that it works, but there were some debugging Xproblems. :-) X XAfter I got it working, I added the graphics, which are pretty good and Xvery well behaved, but it's hard to differentiate the gray shades in Xthe output. I was going to map them to colors, but that didn't help on Xgrayscale displays. X XThen I changed most of the names. If you change the names back to Xsensible things, the program is much more readable. It's kind of a Xcheap trick, but not one unheard of in The Real World. :-) X XLastly, I munged the formatting in subtle ways to make visual grouping Xmore annoying. I also dropped a name that looks like a radix number (I Xwas going to exploit that more fully but didn't get to it) and some Xlexically unpleasing names (like \). X XMy LaserWriter found \ so unpleasant that it wouldn't run the code Xcorrectly. That explains the patch that changed "/\" to (\\) cvn. XChange it back if your scanner can handle it (it >should<). X XI did not, though it was suggested, change or delete the strings Xprinted as informative messages by the program. That would have made Xit much harder to figure out, but I thought some clues were a good Xidea. The idea was to make it tricky to figure out, but give you some Xgood places to start. X XI think this program is a good example of a real program that is fairly Xwell implemented but still hard to follow. It's also brief enough to Xprint out and mull over over lunch. Happy chewing! X X XNotes: X X The game's in a dictionary. X X Note how configurable it is. You can change anything but the X paper size very easily. How would you change that? X X Note the (ab)use of forall throughout. Remember that forall is X polymorphic- that it has different effects with operands of X different types. Do you have to enter your move as a string? X X It's very easy to cheat. How? X X The user interface as text or graphics is very nice, but the X two are different. I wanted them both to be pretty so I didn't X use letters on the graphics. (Plus I didn't know what fonts X were available from gs.) Makes it more confusing too, which is X the point of obfuscation. X X I didn't pack the code into a block of text. That's a rather X weak form of obfuscation if the reader knows how to format X programs better. I did deviate from my normal style to make X parts more confusing, but I feel the program is complicated X enough to stand on its own. :-) X X Note the very small number of names bound in the dictionary X please. Would the code be easier to follow if I'd used a few X more? Why do you think I kept so many things on the stack X (other than to confuse you)? X X This program demonstrates changing the graphic state to make X your life much easier. Well, something like that. X X Note that 16#egad is neither a radix number nor a syntax error. X Why? Also \ does not have any special effect outside of X strings. X X The function "resign" which quits out of the game cleanly is X left as an exercise for the student. END_OF_FILE if test 3984 -ne `wc -c <'mm.ANSWER'`; then echo shar: \"'mm.ANSWER'\" unpacked with wrong size! fi # end of 'mm.ANSWER' fi if test -f 'mm.HINT' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mm.HINT'\" else echo shar: Extracting \"'mm.HINT'\" \(375 characters\) sed "s/^X//" >'mm.HINT' <<'END_OF_FILE' Xmm.ps by Allen Braunsdorf (ab@mentor.cc.purdue.edu) is a game. XYou must run it interactively through a previewer. X X BEST INTERACTIVE -- 1st Prize X -- The best program intended to run interactively through a previewer. X XRun this file and then type: X X please begin game X XWhat now? X XIt can be coaxed to produce graphics. X XEven when you figure it out, it'll keep puzzling you. END_OF_FILE if test 375 -ne `wc -c <'mm.HINT'`; then echo shar: \"'mm.HINT'\" unpacked with wrong size! fi # end of 'mm.HINT' fi if test -f 'mm.ps' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mm.ps'\" else echo shar: Extracting \"'mm.ps'\" \(1588 characters\) sed "s/^X//" >'mm.ps' <<'END_OF_FILE' X13 dict dup begin /holes 4 def /colors 7 def X X/game X{ X /? [ holes { rand colors mod } repeat ] def /. X 12 def 540 holes 1 add div 720 . 1 add div 2 copy gt X { exch } if pop dup dup holes 2 add mul 612 exch sub 2 div add 1 X index dup . 1 add mul 792 exch sub 2 div 792 X exch sub exch 2 div sub translate dup neg X scale 0 setlinewidth X} def X X/-- X{ X dup 0 dup /+ exch def exch { ? X 2 index get eq { X 2 copy colors put /+ + 1 add def 0 16#egad X } if X 1 add X } forall X pop + dup 0 ne { X (Pegs in correct place: ) print dup = X } if X} def X X/++ X{ X exch 0 dup /- exch def 1 holes 1 sub { X dup dup 2 add index exch get colors eq { X pop colors X } { ? exch get } ifelse X } for X holes array astore exch X { X dup colors ne { X 0 1 holes 1 sub { X 2 index exch X 3 copy get eq { X /- - 1 add def X 1 16#egad X colors put X exit X } if X pop pop X } for X } if X pop X } forall X pop X - 0 ne { X (Correct pegs not in correct place: ) print - = X } if X} def X X(\\) cvn X{ X 0 0 0.4 0 360 arc gsave X setgray fill grestore X setgray stroke X } def /16#egad { X 0 exch \ X 1 0 translate X} def X X/* X{ X gsave X 0 . translate X [ exch { X 97 sub dup 0 exch 1 0 translate X colors 1 sub div \ X } forall ] grestore X} def X X/guess X{ X * gsave -0.5 . translate 1 holes 1 add div dup scale -- X ++ grestore holes eq { X (You win!) = showpage end X } { X . 1 sub dup /. exch X def 0 eq { X ? { 97 add } forall ? astore * pop X (You lose. The correct code was \() print 1 string ? X { 1 index 0 3 2 roll put dup print } forall pop (\)) X = showpage end X } if X } ifelse X} def X Xend /please exch def END_OF_FILE if test 1588 -ne `wc -c <'mm.ps'`; then echo shar: \"'mm.ps'\" unpacked with wrong size! fi # end of 'mm.ps' fi if test -f 'mm.unobfs.ps' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'mm.unobfs.ps'\" else echo shar: Extracting \"'mm.unobfs.ps'\" \(5030 characters\) sed "s/^X//" >'mm.unobfs.ps' <<'END_OF_FILE' X%! X%%Title: Commented and formatted version of mm.ps X%%Creator: Allen B (ab@nova.cc.purdue.edu) X X% Refer to the rules of Master Mind if you don't know them. X% X% I believe Master Mind is a trademark of Invicta Plastics for their X% game of codebreaking. X% X% Throughout, suggested names are in () when obfuscated names are used. X X% We will put the whole game in a dictionary so it can be turned on and off. X13 dict dup begin X X% You can change these to make Super Master Mind or whatever X/holes 4 def % length of code X/colors 7 def % possibilities for each code element X X% - game - X% set up the game graphics and code state X/game X{ X % generate the code X /? [ % (answer) X holes { X rand colors mod X } repeat X ] def X X /. 12 def % number of guesses (guesses) X X % Divide the play area up to find peg width or height- use smaller. X % Change 540 and 720 for non US letter pages (I left 1" total margin). X 540 holes 1 add div 720 . 1 add div % (guesses) X 2 copy gt { X exch X } if X pop % the larger one X X % Make new origin at the upper left of the play area. X % Again, 612 x 792 is US letter- change if needed. X dup dup holes 2 add mul 612 exch sub 2 div add X 1 index dup . 1 add mul 792 exch sub 2 div 792 exch sub exch 2 div sub X translate X X % Make a hole the standard unit across and >down< the page. X dup neg scale X X % As usual, this really should be a small non-zero number. X 0 setlinewidth X} def X X% guess -- modifiedguess blacks X% find number of black pegs in score and draw them X% X% The "forall" is really a very strange "for" implemented as X% a very strange "forall". >I< find it hard to follow. X/-- % (black) X{ X dup % keep the guess X 0 % loop index for "forall" X dup /+ exch def % initialize result (blacks) X exch { X % If the code matches the guess, increment + (blacks) and X % put an invalid peg in the guess (which is on the stack) X % so it won't score a hole twice. X ? 2 index get eq { % (answer)[index] X 2 copy colors put % guess[index] = colors X /+ + 1 add def % (blacks) X 0 16#egad % (pegshow) X } if X 1 add % increment index X } forall X pop % the index X + % (blacks) X X % If player got some blacks, tell how many. X dup 0 ne { X (Pegs in correct place: ) print X dup = % (blacks) X } if X} def X X% modifiedguess blacks ++ blacks X% find number of white pegs in score and draw them X% X% Notice the "courtesy" argument that just gets left. Why? To make the X% calling code harder to read, of course. :-) X/++ % (white) X{ X exch % we don't need TOS X 0 % for "for" and to X dup /- exch def % initialize (whites) X X % Go through modifiedguess and build a modified (answer) to X % avoid double scores. X 1 holes 1 sub { X % reach down to get guess from stack X dup dup 2 add index exch get colors eq { X pop colors X } { X ? exch get X } ifelse X } for X holes array astore X X % Still with me? OK, now find the white pegs. That is, wherever X % a peg in (modifiedguess) matches one in (modifiedanswer), X % increment (whites), (pegshow), and invalidate that hole. X % Watch the indexes and pops carefully! X exch { X dup colors ne { X 0 1 holes 1 sub { X 2 index exch X 3 copy get eq { X /- - 1 add def % (whites) X 1 16#egad % (pegshow) X colors put X exit X } if X pop pop X } for X } if X pop X } forall X X pop % the other array X X % If player got some whites, tell how many. X - 0 ne { % (whites) X (Correct pegs not in correct place: ) print X - = % (whites) X } if X} def X X% strokecolor fillcolor \ - X% draw a peg X(\\) cvn % (peg) X{ X 0 0 0.4 0 360 arc X X gsave X setgray X fill X grestore X X setgray X stroke X} def X X% color 16#egad - X% draw a black outlined peg and advance to next hole X/16#egad { % (pegshow) X 0 exch \ % (peg) X 1 0 translate % 1 is 1 >hole< X} def X X% rawguess * guess X% turn an ASCII move into a numeric array and draw it X% at the right place for this guess X/* % (pretty) X{ X gsave X 0 . translate % go down to the right row (guesses) X [ exch { X 97 sub % make 'a' 0 etc. X dup 0 exch % colors for peg X 1 0 translate % move over and X colors 1 sub div \ % (peg) X } forall ] X grestore X} def X X% rawguess guess - X% score a move and update the game state X% X% Notice that this just falls through. It doesn't leave anything on X% the stack either. X/guess X{ X % draw the move X * % (pretty) X X % score and draw the little scoring pegs X gsave X -0.5 . translate % (guesses) X 1 holes 1 add div dup scale X -- % (black) X ++ % (white) X grestore X X % (blacks) is on the stack X holes eq { X (You win!) = X showpage X end X } { X . 1 sub % decrement (guesses) X dup /. exch def % (guesses) X X % if you're out, you lose X 0 eq { X % convert (answer) back to ASCII X ? { % (answer) X 97 add X } forall X ? astore % (answer) X * pop % (pretty) X X % print it out X (You lose. The correct code was \() print X 1 string X ? { X 1 index 0 3 2 roll put X dup print X } forall X pop X (\)) = X X % clean up some X showpage X end X } if X } ifelse X} def X X% now that the dictionary is complete, end it and make it available Xend X/please exch def END_OF_FILE if test 5030 -ne `wc -c <'mm.unobfs.ps'`; then echo shar: \"'mm.unobfs.ps'\" unpacked with wrong size! fi # end of 'mm.unobfs.ps' fi if test -f 'pun.ANSWER' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pun.ANSWER'\" else echo shar: Extracting \"'pun.ANSWER'\" \(315 characters\) sed "s/^X//" >'pun.ANSWER' <<'END_OF_FILE' XThat's not really a bubblesort. X XThe following strings: X X/l (I doubt anyone will be hard put to determine how) def X/m (this works but I thought it was kind of cute -- DD) def X Xare parsed and the substrings "put" and "gt" taken out of them. XThese substrings are used to secretly redefine the /put and /gt Xoperators. END_OF_FILE if test 315 -ne `wc -c <'pun.ANSWER'`; then echo shar: \"'pun.ANSWER'\" unpacked with wrong size! fi # end of 'pun.ANSWER' fi if test -f 'pun.HINT' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pun.HINT'\" else echo shar: Extracting \"'pun.HINT'\" \(301 characters\) sed "s/^X//" >'pun.HINT' <<'END_OF_FILE' Xpun.ps, by David Dubin (dsdst3@icarus.lis.pitt.edu) and XMichael Spring (spring+@pitt.edu), won an honorary mention. X XThis from Michael Spring: X X"pun.ps" is a programmer's pun. As you will see, it is an Xeffort to be unclear by making you believe as an expert that there is Xsomething there that isn't. END_OF_FILE if test 301 -ne `wc -c <'pun.HINT'`; then echo shar: \"'pun.HINT'\" unpacked with wrong size! fi # end of 'pun.HINT' fi if test -f 'pun.ps' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pun.ps'\" else echo shar: Extracting \"'pun.ps'\" \(1951 characters\) sed "s/^X//" >'pun.ps' <<'END_OF_FILE' X%!PS-Adobe-2.0 X%%Creator: Michael B. Spring and David S. Dubin X%%For: the heck of it X%%Title: Bubblesort X%%CreationDate: January 6, 1993 X%%Pages: 1 X%%EndComments X%%BeginProlog X X/l (I doubt anyone will be hard put to determine how) def X/m (this works but I thought it was kind of cute -- DD) def X X/mypal { Xh 1 1 sethsbcolor Xa g z 0 360 arc fill Xgsave Xa g z 0 360 arc clip X/delta z 2 div def Xz -1 0 {/r exch def X h r z div 1 sethsbcolor X a delta sub g delta add r 0 360 arc fill} for X/br z 2 mul def Xbr -.5 z {/r exch def X h 1 z r div sethsbcolor X a delta sub g delta add r 200 450 arc stroke X } for Xgrestore X} def X X/which 2 string def m 21 3 getinterval dup X0 get which exch 0 exch put X2 get which exch 1 exch put X Xwhich cvn {pop pop count 1 sub c1 eq} def X Xl 28 3 getinterval cvn {pop pop y { X dup 0 get 10 mul /a exch def X dup 1 get 10 mul /g exch def X dup 2 get 5 mul /z exch def X dup 3 get .1 mul /h exch def X dup 4 get .1 mul /b exch def X pop mypal /y false def} {pop /y true def} ifelse} def X X X X/bubble_sort { X/the_array exch def Xthe_array length /count exch def X1 1 count 1 sub {/c1 exch def X 1 1 count c1 sub {1 sub /index exch def X the_array index get X the_array index 1 add get X gt {the_array index get X the_array index 1 add get X the_array index 3 -1 roll put X the_array index 1 add 3 -1 roll put X } if } for } for X} def X%%EndProlog X%%Page: 1 1 X0 0 moveto 0 1000 lineto 1000 1000 lineto 1000 0 lineto closepath X0 setgray fill X/i 0 def X/y true def X X[40 30 15 9 5] bubble_sort X[50 60 12 8 4] bubble_sort X[20 20 11 7 10] bubble_sort X[30 45 10 4 6] bubble_sort X[12 12 7 2 8] bubble_sort X Xshowpage X%%EOF END_OF_FILE if test 1951 -ne `wc -c <'pun.ps'`; then echo shar: \"'pun.ps'\" unpacked with wrong size! fi # end of 'pun.ps' fi if test -f 'pun.unobfs.ps' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'pun.unobfs.ps'\" else echo shar: Extracting \"'pun.unobfs.ps'\" \(2036 characters\) sed "s/^X//" >'pun.unobfs.ps' <<'END_OF_FILE' X%!PS-Adobe-2.0 X%%Creator: Michael B. Spring and David S. Dubin X%%For: the heck of it X%%Title: Bubblesort X%%CreationDate: January 6, 1993 X%%Pages: 1 X%%EndComments X%%BeginProlog X X/l (I doubt anyone will be hard put to determine how) def X/m (this works but I thought it was kind of cute -- DD) def X X X% draws the bubble at the appropriate location X/draw-bubble X{ X h 1 1 sethsbcolor X a g z 0 360 arc fill X gsave X a g z 0 360 arc clip X /delta z 2 div def X z -1 0 X { X /r exch def X h r z div 1 sethsbcolor X a delta sub g delta add r 0 360 arc fill X } for X /br z 2 mul def X br -.5 z X { X /r exch def X h 1 z r div sethsbcolor X a delta sub g delta add r 200 450 arc stroke X } for X grestore X} def X X X%% take out X X/which 2 string def Xm 21 3 getinterval dup % (ght) (ght) X0 get which exch 0 exch put X2 get which exch 1 exch put % /which (gt) def X Xwhich cvn % /gt X{ X pop pop count 1 sub c1 eq X} def X Xl 28 3 getinterval % (put) Xcvn % /put X{ X pop pop y X { X dup 0 get 10 mul /a exch def X dup 1 get 10 mul /g exch def X dup 2 get 5 mul /z exch def X dup 3 get .1 mul /h exch def X dup 4 get .1 mul /b exch def X pop draw-bubble /y false def X } X { X pop /y true def X } ifelse X} def X X X% bubble_sort "the_array". X/bubble_sort X{ X /the_array exch def X the_array length /count exch def X 1 1 count 1 sub X { X /c1 exch def X 1 1 count c1 sub X { X 1 sub /index exch def X the_array index get X the_array index 1 add get X gt {the_array index get X the_array index 1 add get X the_array index 3 -1 roll put X the_array index 1 add 3 -1 roll put X } if X } for X } for X} def X%%EndProlog X%%Page: 1 1 X X X%%% draw the surrounding gray box. X0 0 moveto 0 1000 lineto 1000 1000 lineto 1000 0 lineto closepath X0 setgray fill X/i 0 def X/y true def X X[40 30 15 9 5] bubble_sort X[50 60 12 8 4] bubble_sort X[20 20 11 7 10] bubble_sort X[30 45 10 4 6] bubble_sort X[12 12 7 2 8] bubble_sort X Xshowpage X%%EOF END_OF_FILE if test 2036 -ne `wc -c <'pun.unobfs.ps'`; then echo shar: \"'pun.unobfs.ps'\" unpacked with wrong size! fi # end of 'pun.unobfs.ps' fi if test -f 'rules.tex' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'rules.tex'\" else echo shar: Extracting \"'rules.tex'\" \(6313 characters\) sed "s/^X//" >'rules.tex' <<'END_OF_FILE' X\documentstyle{article} X\setlength{\textwidth}{6.5 in} X\setlength{\textheight}{9 in} X\setlength{\topmargin}{0 in} X\setlength{\oddsidemargin}{0 in} X\setlength{\parindent}{0 in} X\begin{document} X X\begin{center} X{\Large 1st International obFUsCaTeD POsTsCripT Contest} X X1993 Rules for the Contest X X{\em Jonathan Monsarrat} (jgm@cs.brown.edu) X X{\em Alena Lacova} (alena@nikhef.nl) X X\end{center} X X\section{What it is} X XA contest of programming skills and knowledge, exclusively for the XPostScript programming language. Its purpose: X X\begin{itemize} X X\item To spread knowledge of PostScript and its details. X X\item To applaud those with the best tricks. X X\item To prove that humans can beat those damnable machine generators Xat their own game by writing the most obscure and mysterious PostScript Xprograms ever. X X\end{itemize} X XWinners will receive the fame and attention that goes with having their Xprogram entry posted as a winner to programmers world-wide. X XPlease forward these rules to anyone you know who may be interested. X XThe fancy Obfuscated PostScript version of these rules is available by Xftp as ``wilma.cs.brown.edu:pub/postscript/obfuscated/rules.ps''. This Xis also the site with the obfuscated contest winners. X X\section{How to Enter} X XWrite a program in PostScript that does something special and Xshows off an interesting quirk of the language or displays a special Xeffect. Almost anything is allowed! Write something creative that Xwill catch the attention of the judges. Your job is not only to make Xsomething special, but to obscure the meaning of your entry by using Xobscure techniques. The people who read your program shouldn't be able Xto figure out how it does what it does. (Yes, it must {\em do} something.) X X\begin{itemize} X X\item Do not use a drawing program like MacDraw. Your contest entry Xcannot be machine-generated in any way. X X\item Your entry can be as large as 5000 bytes. However, quality is Xconsidered far more important than quantity. Entries that are smaller Xthan 1500 bytes and still do something are considered impressive. XYour entry may be multiple files totalling less than this byte limit. X X\item Don't forget to give a filename for your program. X X\item Your contest entry should run on GhostScript 2.5.2 so that a Xwide variety of PostScript users may view your entry if it wins. XThis rule may relunctantly be broken if necessary to the interesting Xfunctionality of your program. GhostScript is a freely available XPostScript interpreter. You may get it from anonymous\\ ftp to Xftp.cs.wisc.edu:/pub/X/ghostscript-*2.5.2*. Your system administrator Xwill be able to tell you how to use ftp. X X\item Your PostScript code should be as portable as possible so that many Xpeople can enjoy running your program if you win. Do not use any commands Xthat are not part of the PostScript language (like the GhostScript Xadditional commands). X X\item Your program must be original. X X\item You may not submit more than twelve entries. X X\item Don't use PostScript 2 commands unless they are an important part of Xyour entry. X X\end{itemize} X X\section{Documentation} X XNot writing documentation will increase the obscureness of your Xentry. Good for you! However, you may wish to document anything Xspecial your program does that is so obscure that the judges might Xmiss it completely. X XIf there is some special hardware that you rely on, or if the device Xsize or resolution are an important part of your entry, that must be Xdocumented. X X\newpage X\section{Where to Send It} X XSend your entry to Jonathan Monsarrat by email to {\bf jgm@cs.brown.edu.} X XIf you don't have email, use this address:\\ XJonathan Monsarrat\\ X14 Danforth Street\\ XRehoboth Massachusetts 02769 U.S.A. X XJon's phone number in the U.S.A. is (401) 863-7695. X XWe welcome your suggestions! Please email your suggestions and questions. X X\section{Categories} X XEntries will be judged by category, with the overall winner being the receiver Xof the Obfuscated PostScript award. Only the winning entries of each category Xwill be included in the contest winners archive. X X\begin{description} X X\item[Obfuscated PostScript] The most obscure PostScript program. It does Xsomething in a clever way, and took us forever to figure out (if we did). X X\item[Best Artwork] The best example of art. X X\item[Most Compact] The best example of very tiny coding. How Xmuch less than 1000 bytes can an interesting program be? X X\item[Best PostScript 1] The best entry that used only PostScript 1 commands. X X\item[Best Non-Graphics] The best entry that did not have a graphical Xoutput. X X\item[Best Interactive Program] The best entry that you type interactive Xcommands to with an on-line interpreter. X X\item[Most Useful] The entry most likely to be of some real use. X X\end{description} X XAnd anything so unusual and creative that it deserves an award. X X\section{Judging} X XThe judges will choose the winners of each category. X X{\bf Alena Lacova} is a system administrator at NIKHEF (Institute for XHigh Energy and Nuclear Physics) in the XNetherlands. She is the author of {\em The PostScript Chaos Programs,} Xwhich draw Julia sets, Mandelbrot sets and other kinds of fractal Xfunctions. X X{\bf Jonathan Monsarrat} is a graduate student from MIT and Brown University Xin the U.S.A. He is the FAQ maintainer for the Usenet newsgroup X{\bf comp.lang.postscript} and the author of {\em The PostScript Zone} and X{\em LameTeX}. X X\section{Deadline and Schedule} X XSubmissions will be accepted after 12:01 a.m GMT, Sunday November 29th, X1992. Your submission must be postmarked before 11:59 p.m. GMT, XSunday January 10th, 1993. We must receive it before 11:59 p.m. GMT, XMonday January 11th, 1993. X XResults will be posted as soon as we have them (probably in a couple Xof weeks), but no later than Sunday, January 31st. Results will go out Xto {\bf comp.lang.postscript} (and a few well-chosen Usenet newsgroups), the XCompuserve group, and with the Adobe Developer's mailing. Copies of the Xwinning entries will be available by email and anonymous ftp, and Xalso by surface mail on computer diskettes for a small fee (if there is a Xdemand). X X% \begin{stealth} X% This document was written with the LaTeX language and formatted by LameTeX, X% the PostScript hacker's LaTeX. X% \end{stealth} X X{\sc PostScript} is a registered trademark of Adobe Systems, Incorporated. X X\end{document} END_OF_FILE if test 6313 -ne `wc -c <'rules.tex'`; then echo shar: \"'rules.tex'\" unpacked with wrong size! fi # end of 'rules.tex' fi if test -f 'rules.txt' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'rules.txt'\" else echo shar: Extracting \"'rules.txt'\" \(7099 characters\) sed "s/^X//" >'rules.txt' <<'END_OF_FILE' X 1st International obFUsCaTeD POsTsCripT Contest X 1993 Rules for the Contest X Jonathan Monsarrat (jgm@cs.brown.edu) X Alena Lacova (alena@nikhef.nl) X X 1 What it is X X A contest of programming skills and knowledge, exclusively for X the PostScript programming language. Its purpose: X X * To spread knowledge of PostScript and its details. X X * To applaud those with the best tricks. X X * To prove that humans can beat those damnable machine X generators at their own game by writing the most obscure and X mysterious PostScript programs ever. X Winners will receive the fame and attention that goes with X having their program entry posted as a winner to programmers X world-wide. X Please forward these rules to anyone you know who may be X interested. X The fancy Obfuscated PostScript version of these rules is X available by ftp as X ``wilma.cs.brown.edu:pub/postscript/obfuscated/rules.ps''. This X is also the site with the obfuscated contest winners. X X 2 How to Enter X X Write a program in PostScript that does something special and X shows off an interesting quirk of the language or displays a X special effect. Almost anything is allowed! Write something X creative that will catch the attention of the judges. Your job X is not only to make something special, but to obscure the X meaning of your entry by using obscure techniques. The people X who read your program shouldn't be able to figure out how it X does what it does. (Yes, it must do something.) X X * Do not use a drawing program like MacDraw. Your contest entry X cannot be machine-generated in any way. X X * Your entry can be as large as 5000 bytes. However, quality is X considered far more important than quantity. Entries that are X smaller than 1500 bytes and still do something are considered X impressive. Your entry may be multiple files totalling less X than this byte limit. X X * Don't forget to give a filename for your program. X X * Your contest entry should run on GhostScript 2.5.2 so that a X wide variety of PostScript users may view your entry if it X wins. This rule may relunctantly be broken if necessary to X the interesting functionality of your program. GhostScript is X a freely available PostScript interpreter. You may get it X from anonymous X X ftp to ftp.cs.wisc.edu:/pub/X/ghostscript-*2.5.2*. Your X system administrator will be able to tell you how to use ftp. X X * Your PostScript code should be as portable as possible so X that many people can enjoy running your program if you win. X Do not use any commands that are not part of the PostScript X language (like the GhostScript additional commands). X X * Your program must be original. X X * You may not submit more than twelve entries. X X * Don't use PostScript 2 commands unless they are an important X part of your entry. X X 3 Documentation X X Not writing documentation will increase the obscureness of your X entry. Good for you! However, you may wish to document anything X special your program does that is so obscure that the judges X might miss it completely. X If there is some special hardware that you rely on, or if the X device size or resolution are an important part of your entry, X that must be documented. X X 4 Where to Send It X X Send your entry to Jonathan Monsarrat by email to X jgm@cs.brown.edu. X If you don't have email, use this address: X X Jonathan Monsarrat X X 14 Danforth Street X X Rehoboth Massachusetts 02769 U.S.A. X Jon's phone number in the U.S.A. is (401) 863-7695. X We welcome your suggestions! Please email your suggestions and X questions. X X 5 Categories X X Entries will be judged by category, with the overall winner X being the receiver of the Obfuscated PostScript award. Only the X winning entries of each category will be included in the X contest winners archive. X X Obfuscated PostScript X The most obscure PostScript program. It does something in a X clever way, and took us forever to figure out (if we did). X X Best Artwork X The best example of art. X X Most Compact X The best example of very tiny coding. How much less than 1000 X bytes can an interesting program be? X X Best PostScript 1 X The best entry that used only PostScript 1 commands. X X Best Non-Graphics X The best entry that did not have a graphical output. X X Best Interactive Program X The best entry that you type interactive commands to with an X on-line interpreter. X X Most Useful X The entry most likely to be of some real use. X And anything so unusual and creative that it deserves an award. X X 6 Judging X X The judges will choose the winners of each category. X Alena Lacova is a system administrator at NIKHEF (Institute for X High Energy and Nuclear Physics) in the Netherlands. She is the X author of The PostScript Chaos Programs, which draw Julia sets, X Mandelbrot sets and other kinds of fractal functions. X Jonathan Monsarrat is a graduate student from MIT and Brown X University in the U.S.A. He is the FAQ maintainer for the X Usenet newsgroup comp.lang.postscript and the author of The X PostScript Zone and LameTeX. X X 7 Deadline and Schedule X X Submissions will be accepted after 12:01 a.m GMT, Sunday X November 29th, 1992. Your submission must be postmarked before X 11:59 p.m. GMT, Sunday January 10th, 1993. We must receive it X before 11:59 p.m. GMT, Monday January 11th, 1993. X Results will be posted as soon as we have them (probably in a X couple of weeks), but no later than Sunday, January 31st. X Results will go out to comp.lang.postscript (and a few X well-chosen Usenet newsgroups), the Compuserve group, and with X the Adobe Developer's mailing. Copies of the winning entries X will be available by email and anonymous ftp, and also by X surface mail on computer diskettes for a small fee (if there is X a demand). X This document was written with the LaTeX language and formatted X by LameTeX, the PostScript hacker's LaTeX. X PostScript is a registered trademark of Adobe Systems, X Incorporated. END_OF_FILE if test 7099 -ne `wc -c <'rules.txt'`; then echo shar: \"'rules.txt'\" unpacked with wrong size! fi # end of 'rules.txt' fi if test -f 'sig.ANSWER' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sig.ANSWER'\" else echo shar: Extracting \"'sig.ANSWER'\" \(1327 characters\) sed "s/^X//" >'sig.ANSWER' <<'END_OF_FILE' XAllen writes: X XThis program is my PostScript geek .signature. It prints my email Xaddress out on the current output channel. X XIt works by converting the elements of the array of numbers either into Xbase 32 numbers or ASCII characters. Since all digits above 9 are Xrepresented by capital letters, you can spell words with them. X XNotes: X X The save and restore pair isn't really needed, but was included X to fill out the two lines and protect the current dictionary X (in case - was already bound to something). X X The 99 could have been higher or lower (how much?), but it X looks good and confused some people. It makes people think X base 10, which fogs the mind of the reader. :-) X X The base of 32 should be higher if you want to be able to do X the whole alphabet. What's the lowest value I could have X used? X X =string is a cheap way to get around defining another string. X I don't know how portable that really is, but Adobe PostScripts X like it fine. Don't count on it keeping its value though! X X I had used \ instead of -, but I found this more pleasing to X the eye. The point was to have a pretty .signature, not X necessarily an efficient or maximally obfuscated one. :-) X X--- Xsave /- 1 string def[331 64 779242 46 396 46 871217102 46 14782 10]{dup X99 lt{- 0 3 -1 roll put -}{32 =string cvrs}ifelse print} forall restore END_OF_FILE if test 1327 -ne `wc -c <'sig.ANSWER'`; then echo shar: \"'sig.ANSWER'\" unpacked with wrong size! fi # end of 'sig.ANSWER' fi if test -f 'sig.HINT' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sig.HINT'\" else echo shar: Extracting \"'sig.HINT'\" \(370 characters\) sed "s/^X//" >'sig.HINT' <<'END_OF_FILE' Xsig.ps, by Allen Braunsdorf (ab@mentor.cc.purdue.edu) won an honorable mention. X XThis was originally developed to fit in a certain amount of space and Xbe pleasing to eye as source code. But what does it do? How? X XHere are some hints to help you: X X This program has no graphic output. X X What does cvrs do? X X What's this program called? X XRun this program interactively. END_OF_FILE if test 370 -ne `wc -c <'sig.HINT'`; then echo shar: \"'sig.HINT'\" unpacked with wrong size! fi # end of 'sig.HINT' fi if test -f 'sig.ps' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sig.ps'\" else echo shar: Extracting \"'sig.ps'\" \(144 characters\) sed "s/^X//" >'sig.ps' <<'END_OF_FILE' Xsave /- 1 string def[331 64 779242 46 396 46 871217102 46 14782 10]{dup X99 lt{- 0 3 -1 roll put -}{32 =string cvrs}ifelse print} forall restore END_OF_FILE if test 144 -ne `wc -c <'sig.ps'`; then echo shar: \"'sig.ps'\" unpacked with wrong size! fi # end of 'sig.ps' fi if test -f 'sird.HINT' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sird.HINT'\" else echo shar: Extracting \"'sird.HINT'\" \(1170 characters\) sed "s/^X//" >'sird.HINT' <<'END_OF_FILE' Xsird.ps by Stephen Peters (speters@us.oracle.com) is a random-dot Xstereogram in only 603 bytes (plus header)! X XBEST OBFUSCATED ARTWORK -- 2nd prize X -- The 2nd most coveted prize. These combine obfuscation with great artwork. X XThe sird.ps program produces an output which looks like a large rectangle, Xrandomly filled with dots, and two large circles at the top. This is called a Xrandom-dot stereogram, and has occasionally been referred to as a sird. In Xorder to view the image, cross your eyes until the two circles at the top merge Xinto one (it should now look as if there are three circles at the top). Now, Xfocus on the center dot, and your brain should start interpreting the dots as Xpart of a 3-D picture. It will be as if part of the field of dots is "warped" Xtoward or away from you. X XIf you can't focus on the central dot, try focusing first on objects close to Xyou or far away from you until you get the right effect. Don't feel bad if you Xcan't get it at first -- it's something that takes practice! X XIf this peaks your interest, try Games magazine from (around) April '92 -- Xthere's an article on the creation, and several example sirds to look at! END_OF_FILE if test 1170 -ne `wc -c <'sird.HINT'`; then echo shar: \"'sird.HINT'\" unpacked with wrong size! fi # end of 'sird.HINT' fi if test -f 'sird.ps' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sird.ps'\" else echo shar: Extracting \"'sird.ps'\" \(631 characters\) sed "s/^X//" >'sird.ps' <<'END_OF_FILE' X%!PS -- Obfuscated PS entry X/A/mul/B/def/C/pop/D/bitshift/E/for/F/and/G/idiv/I/add/K/exch/L/put/M/dup/N X/roll/O/copy/P/sub/S/index/U/get/X/arc/Y/fill 18{load def}repeat/n -100/i 99 X/h 100/s 2500/w .1/x 360/z 300/o 200 8{B}repeat/v{72 A}B/g{0 0 1 7{C 1 D rand X3 F 3 G 1 xor I}E}B/a 7500 string B 0 1 s 1 P{a K g L}E n 1 i{n 1 i{K M 3 1 N X2 O M A K M A I 4900 K P M 0 lt{C 0}if 490 G 25 A 3 1 N h I o A K h I I 1 1 S X8 mod D K 8 G a 1 S 5 -1 N I U 2 S F 3 1 N s I a 1 S U 255 4 -1 N P F 3 -1 N Xor a 3 1 N L}E C}E 1 v 6 v translate 2 v 4 w I v w v 0 x X Y 4 v 4 w I v w v X0 x X Y 6 v 4 v scale o z 1[0 z 0 o P 0 o 0]{a}image showpage END_OF_FILE if test 631 -ne `wc -c <'sird.ps'`; then echo shar: \"'sird.ps'\" unpacked with wrong size! fi # end of 'sird.ps' fi if test -f 'sird.unobfs.ps' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sird.unobfs.ps'\" else echo shar: Extracting \"'sird.unobfs.ps'\" \(1243 characters\) sed "s/^X//" >'sird.unobfs.ps' <<'END_OF_FILE' X%!PS -- Obfuscated PS entry X%%% fills an array X X/inch {72 mul} def X X/bigarray 7500 string def % The array to be filled with image information X X0 1 2500 1 sub % a big for loop for filling the array X{ X bigarray exch X 0 0 1 7 X { X pop 1 bitshift % calculate a value X rand 3 and 3 idiv 1 xor add % add random factor X } for X put % put calculated value in array X} for X X-100 1 99 % the hard part. For a double-dimension array 200x200 X{ % calculates bit information at each point. X -100 1 99 X { X exch dup 3 1 roll 2 copy dup mul exch dup mul add X 4900 exch sub dup 0 lt X { X pop 0 X } if X 490 idiv 25 mul 3 1 roll 100 add X 200 mul exch 100 add add 1 1 index 8 mod bitshift X exch 8 idiv bigarray 1 index X 5 -1 roll add get 2 index and 3 1 roll 2500 add X bigarray 1 index get 255 4 -1 roll sub and 3 -1 roll X or bigarray 3 1 roll put X } for X pop X} for X X1 inch 6 inch translate X2 inch 4 .1 add inch .1 inch 0 360 arc % draw the alignment circles Xfill X4 inch 4 .1 add inch .1 inch 0 360 arc % draw the alignment circles Xfill X6 inch 4 inch scale X% draw the actual bitmap of the stereogram. X200 300 1 [0 300 0 200 sub 0 200 0] { bigarray } image Xshowpage END_OF_FILE if test 1243 -ne `wc -c <'sird.unobfs.ps'`; then echo shar: \"'sird.unobfs.ps'\" unpacked with wrong size! fi # end of 'sird.unobfs.ps' fi if test -f 'square-dance.ANSWER' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'square-dance.ANSWER'\" else echo shar: Extracting \"'square-dance.ANSWER'\" \(3115 characters\) sed "s/^X//" >'square-dance.ANSWER' <<'END_OF_FILE' XINTERESTING NOTES: X XDon't overlook the instructions in the file! They explain (somewhat Xbriefly) how to fully appreciate the art work. X XNote that this is not merely a static lump of code: this is a fully Xparameterized program. Try fiddling with the parameters at the top of the Xfile (they are explained below). X XTHE OBFUSCATION: X XThe obfuscation is in two parts: 1) the underlying logic of the program is Xsomewhat mysterious, and 2) the lexical structure has been heavily Xmanipulated to shorten the file as much as possible. X XThere are no particularly obscure uses of the language, except possibly Xplaying around with the order of operations: arguments may be pushed on Xthe stack, and used later than would be expected. For example, a number of Xdef's are deferred until they can be done in one batch. Also, the open and Xclose square brackets are used as ordinary names to save some space since Xthey are self-delimiting. X XWHAT IS IT: X XThis is an example of a parquet deformation, the subject of Douglas XHofstadter's July 1983 Metamagical Themas column in Scientific American. XThe column is reprinted as chapter 10 of Hofstadter's book Metamagical XThemas (Basic Books, 1985). The idea behind a parquet deformation is to Xtake a regular tiling of the plane and deform it gradually: at any point, Xyou have a regular tiling, but at each point, it is slightly different. XThe change is gradual and continuous. The idea borrows heavily from XM. C. Escher's Metamorphosis pictures. X XThis particular parquet deformation is original to me, and happens to lend Xitself quite nicely to generation by a small PostScript program. Xsquare-dance.ps is an example of a parquet deformation, the subject of XDouglas Hofstadter's July 1983 Metamagical Themas column in Scientific XAmerican. The column is reprinted as chapter 10 of Hofstadter's book XMetamagical Themas (Basic Books, 1985). The idea behind a parquet Xdeformation is to take a regular tiling of the plane and deform it Xgradually: at any point, you have a regular tiling, but at each point, Xit is slightly different. The change is gradual and continuous. The Xidea borrows heavily from M. C. Escher's Metamorphosis pictures. X XThis particular parquet deformation is original to me, and happens to lend Xitself quite nicely to generation by a small PostScript program. X XTHE PARAMETERS EXPLAINED: X XSee the HINT file. X XHOW THE PROGRAM WORKS: X XThis particular parquet deformation can be analyzed into a number of Xdifferent zig-zag lines, where the size and angle of the zigs and zags Xchanges over time, giving the parquet its deformation. At the heart of the Xcode is a procedure (called v) which takes a y coordinate, and four numbers Xon the stack, which get used as the arguments to two lineto's. This Xroutine gets called repeatedly to make the zigs and zags, which eventually Xget stroked. X XThe program loops along the strips, creating a clipping region around the Xstrip, and translating the coordinate system so that the strips are joined Xup end to end. Then within each strip, two for loops create the lines Xacross the strip and the lines along the strip. END_OF_FILE if test 3115 -ne `wc -c <'square-dance.ANSWER'`; then echo shar: \"'square-dance.ANSWER'\" unpacked with wrong size! fi # end of 'square-dance.ANSWER' fi if test -f 'square-dance.HINT' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'square-dance.HINT'\" else echo shar: Extracting \"'square-dance.HINT'\" \(1282 characters\) sed "s/^X//" >'square-dance.HINT' <<'END_OF_FILE' Xsquare-dance.ps by Ned Batchelder (batcheldern@hannah.enet.dec.com) is Xa metamorphosis drawing program. X XOBFUSCATED CONTEST WINNER -- 2nd Prize X-- The most coveted prize. The most maliciously tangled, yet functional, code. X XThis program also has a number of parameters that can be changed. Try Xexperimenting and see what results you get! X XThe first two (612 792) are clear to anyone who has spent too much time in XNorth America thinking in points: these are the dimension of the sheet. XChange them if you want to print on something other than letter-size paper. X XThe next (36) is the width of the blank area around the edge of the sheet. X XThe next (4) is how many strips to create. Increasing it will produce more Xstrips, so the deformation will be more gradual, but the strips will be Xnarrower. X XThe next (9) is the size (in points) of the grid underlying the parquet. XIncreasing this will give larger tiles. X XAt the beginning and end of the transformation, there is an area which Xdoesn't transform at all. The last parameter (99) is the length (in Xpoints) of this area. X XSomewhere in the code are assembly instructions for this drawing. X XWhat do you think "<5B>{exch def}def" does? Note: [ and ] are self-delmiting. XNo whitespace required. X XNote that it is only 696 bytes. END_OF_FILE if test 1282 -ne `wc -c <'square-dance.HINT'`; then echo shar: \"'square-dance.HINT'\" unpacked with wrong size! fi # end of 'square-dance.HINT' fi if test -f 'square-dance.ps' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'square-dance.ps'\" else echo shar: Extracting \"'square-dance.ps'\" \(696 characters\) sed "s/^X//" >'square-dance.ps' <<'END_OF_FILE' X%! X612 792 36 4 9 99 X/translate/stroke/grestore/gsave/lineto/roll/pop/dup/exch/div/add/mul/neg X/def/repeat/for X(CutSTRIPs&JoinUp) X/N(B)def{N 0 3 2 roll put load N exch def}forall<5B>{P Xt}t<5D>{sub}t/e[/d[/B[/a[/c[/h[/l 0/r 1/b 2/f{transform b{round .6 R P}u Xitransform}/g{f o f o}/j{l l f moveto}/k{i p j}/m{C U n}/q{d b T}/v{e]w B T Xe]e]I s l lt{& l}{s r gt{& r}if}ifelse d T .6 T s b T b{r index S}u}/x{v X4}/y{l q]q z q R}/A{D q]q D w R q R}/z h a]a]B I/w c a]a]15{t}u .1 Xsetlinewidth a a p l r B r]{w T/D[i j z w l w g z l f o i U n clip l D S p Xy{s D d]k A{d R v g l q p}m d R D q]k A{x r J g l q p}m}C A{d R/E[q S E k Xy{& E v g q l p}m d S E d]k y{& E d]x 3 J g q l p}m}C n z l p}C Xshowpage END_OF_FILE if test 696 -ne `wc -c <'square-dance.ps'`; then echo shar: \"'square-dance.ps'\" unpacked with wrong size! fi # end of 'square-dance.ps' fi if test -f 'square-dance.unobfs.ps' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'square-dance.unobfs.ps'\" else echo shar: Extracting \"'square-dance.unobfs.ps'\" \(3721 characters\) sed "s/^X//" >'square-dance.unobfs.ps' <<'END_OF_FILE' X%! square-dance.unobfus.ps X X%%%%%%%%%%%% Make definitions %%%%%%%%%%%%%%%%% X% /translate X% /stroke X% /grestore X% /gsave X% /lineto X% /roll X% /pop X% /dup X% /exch X% /div X% /add X% /mul X% /neg X% /def X% /repeat X% /for X% (CutSTRIPs&JoinUp) X% X% %(C=67 u=117 t=116 S=83 T=84 R=82 I=73 P=80 X% %s=115 &=38 J=74 o=111 i=105 n=110 U=85 p=112 ) X% X% /N(B)def %78=N 66=B X% X% {N 0 3 2 roll put load N exch def}forall X% X% /p { translate } def X% /U { stroke } def X% /n { grestore } def X% /i { gsave } def X% /o { lineto } def X% /J { roll } def X% /& { pop } def X% /s { dup } def X% /P { exch } def X% /I { div } def X% /R { add } def X% /T { mul } def X% /S { neg } def X% /t { def } def X% /u { repeat } def X% /C { for } def X X%%%%%%%%%%%%%%%%%%%%%%%%%%%% strange definitions %%%%%%%%%%%%% X% This defines '[' to mean exch def. Weird, huh? X% <5B>{exch def}def %<5B>=[ -> exch def X% This defines ']' to mean sub. X% <5D>{sub}def %<5D>=] -> sub X X%%%%%%%%%%%%%%%%%%%%%%%%% parameters %%%%%%%%%%%%%%%%%%%%%%%%%%% X/width 612 def % width of the sheet % was h X/height 792 def % height of the sheet % was c X/margin 36 def % margin % was a X/numstrips 4 def % how many strips to create % was B X/gridsize 9 def % size of the grid % was d X/initlength 99 def % the length to not transform % was e X X%%%%%%%%%%%%%%%%%%%%%%%%%%%% yet more definitions %%%%%%%%%%%%%%%%%% X% /l 0 def X% /r 1 def X% /b 2 def X/transformation X{ X transform X 2 X { X round .6 add exch X } repeat X itransform X} def X X/g X{ X transformation lineto X transformation lineto X} def X X% /j{0 0 transformation moveto} def X% /k{gsave translate 0 0 transformation moveto} def X% /m{for stroke grestore} def X X/doublegridsize X{ X gridsize 2 mul X} def X X/v X{ X initlength sub stripheight numstrips mul X initlength sub initlength sub div dup 0 lt X { X pop 0 X } X { X dup 1 gt X { X pop 1 X } if X } ifelse X gridsize mul .6 mul dup 2 mul X 2 X { X 1 index neg X } repeat X} def X X% /x{v 4} def X X/y X{ X 0 doublegridsize sub doublegridsize X stripwidth doublegridsize add X} def X X/A X{ X far-along doublegridsize sub doublegridsize X far-along stripheight add doublegridsize add X} def X X/stripwidth width margin sub margin sub numstrips div def % was z X/stripheight height margin sub margin sub def % was w X X% 15{def}repeat defines previous 15 variables X X.1 setlinewidth Xmargin margin translate X X% This for loop goes once for each strip. X0 1 numstrips 1 sub X{ X stripheight mul /far-along exch def % How far along in the "joined strip". X gsave X X % draw the outline for the strip. X 0 0 transformation X moveto X stripwidth stripheight 0 stripheight g X stripwidth 0 transformation X lineto X gsave X stroke X grestore X clip X X % X 0 far-along neg translate X y X { X dup far-along gridsize sub X gsave X translate X 0 0 transformation X moveto A X { X gridsize add v g 0 doublegridsize translate X } X for X stroke X grestore X gridsize add far-along doublegridsize sub X gsave X translate X 0 0 transformation X moveto A X { X v 4 1 roll X g 0 doublegridsize translate X } for X stroke X grestore X } for X A X { X gridsize add X /E exch def X doublegridsize neg E gsave translate 0 0 transformation moveto y X { X pop E v g doublegridsize 0 translate X } for stroke grestore X gridsize neg E gridsize sub gsave translate 0 0 transformation moveto y X { X pop E gridsize sub v 4 3 roll X g doublegridsize 0 translate X } for stroke grestore X } for X grestore X stripwidth 0 translate % go to start of next strip X} for Xshowpage X END_OF_FILE if test 3721 -ne `wc -c <'square-dance.unobfs.ps'`; then echo shar: \"'square-dance.unobfs.ps'\" unpacked with wrong size! fi # end of 'square-dance.unobfs.ps' fi echo shar: End of shell archive. exit 0