home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / sources / misc / 3921 < prev    next >
Encoding:
Text File  |  1992-09-10  |  54.6 KB  |  1,787 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: chongo@toad.com (Landon Curt Noll)
  4. Subject:  v32i030:  ioccc.1992 - 1992 International Obfuscated C Code Contest winners, Part03/05
  5. Message-ID: <1992Sep10.154442.27179@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: 0a668225acf2082a538a528eaf25d394
  8. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  9. Reply-To: chongo@hoptoad.UUCP (Landon C. Noll)
  10. Organization: Nebula Consultants in San Francisco
  11. References: <csm-v32i028=ioccc.1992.103926@sparky.IMD.Sterling.COM>
  12. Date: Thu, 10 Sep 1992 15:44:42 GMT
  13. Approved: kent@sparky.imd.sterling.com
  14. Lines: 1771
  15.  
  16. Submitted-by: chongo@toad.com (Landon Curt Noll)
  17. Posting-number: Volume 32, Issue 30
  18. Archive-name: ioccc.1992/part03
  19. Environment: C
  20.  
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line, then feed it
  23. # into a shell via "sh file" or similar.  To overwrite existing files,
  24. # type "sh file -c".
  25. # Contents:  1992/README 1992/adrian.hint 1992/adrian.orig.c
  26. #   1992/albert.orig.c 1992/imc.hint 1992/nathan.hint 1992/third
  27. #   1992/vern.hint 1992/vern.orig.c 1992/westley.hint
  28. # Wrapped by kent@sparky on Thu Sep 10 10:21:21 1992
  29. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  30. echo If this archive is complete, you will see the following message:
  31. echo '          "shar: End of archive 3 (of 5)."'
  32. if test -f '1992/README' -a "${1}" != "-c" ; then 
  33.   echo shar: Will not clobber existing file \"'1992/README'\"
  34. else
  35.   echo shar: Extracting \"'1992/README'\" \(3693 characters\)
  36.   sed "s/^X//" >'1992/README' <<'END_OF_FILE'
  37. X1992 marked the "The Ninth International Obfuscated C Code Contest"
  38. X
  39. XUse make to compile entries.  It is possible that on BSD or non-unix
  40. Xsystems the makefile needs to be changed.  See the Makefile for details.
  41. X
  42. XLook at the source and try to figure out what the programs do, and run
  43. Xthem with various inputs.  If you want to, look at the hints files for
  44. Xspoilers - this year we included most of the information included
  45. Xby the submitters.
  46. X
  47. XRead over the makefile for compile/build issues.  Your system may
  48. Xrequire certain changes (add or remove a library, add or remove a
  49. X#define).  A number of compilers had problems optimizing certain
  50. Xentries.  Some compilers do optimize, but the resulting program
  51. Xdoes not work.  By default we have left off -O from compile lines.  
  52. XYou might want to add -O back, or add it back for certain entries
  53. Xwhere performance is important.
  54. X
  55. XThis year marked an all time high for number of entries as well as the
  56. Xquality of entries.  Nearly twice the usual number of entries made it
  57. Xto the final judging rounds.  Even when we raised the standards for
  58. Xwinning, we still wound giving out a few more awards than in other
  59. Xyears.  The new size rules size probably contributed to the overall
  60. Xhigh quality.
  61. X
  62. XFYI: By tradition, we do not record the count the number entries,
  63. X     nor do we give our our guess as to the number of entries 
  64. X     received.  For folks who wonder, we can say that we consumed 
  65. X     about 2000 pages of output (printing between 2 and 4 normal 
  66. X     pages per side) during the judging process this year.
  67. X
  68. XThe new instructions for submitting entries worked well - we were
  69. Xable to write scripts to unpack them and eliminate duplicates.
  70. X
  71. XAs promised last year, we accepted programs that made use of the X
  72. Xlibraries for the first time.  We now consider ANSI C compilers to be
  73. Xthe "standard" version that the entries were compiled with.
  74. X
  75. XName and address information are separated from the actual program
  76. Xprior to judging.  This eliminates any chance that we would bias our
  77. Xjudging for/against any person or group.  In the end, we are surprised
  78. Xas you are to see who as won.  Even so, it is worth noting that
  79. XBrian Westley has submitted a winning entry for the past 6 years!
  80. X
  81. X
  82. XA few notes regarding future contests:
  83. X
  84. XWe did not give awards to some traditional contest categories such as
  85. X"Best Layout".  We felt that to do so would deny awards to more
  86. Xdeserving entries.  These categories have not been eliminated.  We will
  87. Xlikely be awarding them in future years.
  88. X
  89. XWe received a few entries whose instructions were rot13'd.  While
  90. Xnothing was said about this in the rules, we found that it made the 
  91. Xjudging process a little harder, so we may request that this not
  92. Xbe done this in the future.
  93. X
  94. XSome thought has been given to a separate obfuscated perl contest.
  95. XWatch comp.lang.perl for details!
  96. X
  97. XBe sure to wait until the 1993 rules are posted before submitting entries.  
  98. XWe may fine tune the rules to reflect the some ideas above.
  99. X
  100. XPlease send us comments and suggestions what we have expressed above.
  101. XAlso include anything else that you would like to see in future contests.
  102. XSend such email to:
  103. X
  104. X    ...!{sun,pacbell,uunet,pyramid}!hoptoad!judges
  105. X    judges@toad.com
  106. X
  107. X
  108. XIf you use, distribute or publish these entries in some way, please drop
  109. Xus a line.  We enjoy seeing who, where and how the contest is used.
  110. X
  111. XIf you have problems with any of the entries, AND YOU HAVE A FIX, please
  112. XEmail the fix (patch file or the entire changed file) to the above address.
  113. X
  114. XCredits:
  115. X
  116. XWe would like to thank Barbara Frezza for her role as official chef of
  117. Xthe contest.  Landon Noll and Larry Bassel appreciated the opportunity
  118. Xto serve as official taste testers. Yummo!
  119. END_OF_FILE
  120.   if test 3693 -ne `wc -c <'1992/README'`; then
  121.     echo shar: \"'1992/README'\" unpacked with wrong size!
  122.   fi
  123.   # end of '1992/README'
  124. fi
  125. if test -f '1992/adrian.hint' -a "${1}" != "-c" ; then 
  126.   echo shar: Will not clobber existing file \"'1992/adrian.hint'\"
  127. else
  128.   echo shar: Extracting \"'1992/adrian.hint'\" \(7292 characters\)
  129.   sed "s/^X//" >'1992/adrian.hint' <<'END_OF_FILE'
  130. XMost Educational: <adrian@u.washington.edu> Adrian Mariano
  131. X
  132. X    Adrian Mariano
  133. X    University of Washington
  134. X    2729 72nd Ave SE
  135. X    Mercer Island, WA 98040
  136. X    USA
  137. X
  138. X
  139. XJudges' comments:
  140. X
  141. X    To build:
  142. X    make adrian
  143. X
  144. X    Try:
  145. X    adrian adrian.grep.try < adrian.hint
  146. X    
  147. X    For the slow minded, try:
  148. X    adsleep 32767
  149. X    
  150. X    Once you get past the obfuscation, you have an opportunity to learn
  151. X    about regular expressions and state machines.
  152. X
  153. X    NOTE: Some compilers have had trouble optimizing this entry.
  154. X
  155. X
  156. XSelected notes from the author:
  157. X
  158. X                            ADrian's GREP (adgrep)
  159. X
  160. X    For those confused by the complexity of full-blown egrep style regular
  161. X    expressions, this program offers an alternative.  It implements an
  162. X    equivalent search, using a deterministic finite automaton.
  163. X
  164. X    A deterministic finite automaton consists of a finite set of states,
  165. X    along with transition rules to move from one state to another, an initial
  166. X    state, and a set of accepting states.  The automaton takes a string as
  167. X    input and begins in the start state.  It reads a character of the string
  168. X    and consults the rules for the current state, moving to the new state
  169. X    indicated by the appropriate rule.  This process is repeated until the
  170. X    string is consumed.  If the current state at this point is one of the
  171. X    accepting states, then the string is accepted.
  172. X
  173. X    The deterministic finite automaton is specified as a series of rules for
  174. X    each state:
  175. X
  176. X       <state> chars1 <dest1> chars2 <dest2> ...
  177. X
  178. X    chars1 is a list of characters (only the first 8 are significant) which
  179. X    should trigger a transition to <dest1>.  <dest1> is another state which
  180. X    should have a similar specification somewhere.  A state is accepting if
  181. X    it is specified in square brackets: [final], and state strings are
  182. X    significant to only eight characters.
  183. X
  184. X    Example 1: matches ^abc$
  185. X
  186. X    <q0> a <q1>          The first state to appear is the start state
  187. X    <q1> b <q2>
  188. X    <q2> c [q3]
  189. X    [q3]
  190. X
  191. X    Technically, a deterministic finite automaton should have a rule for each
  192. X    possible input character at each state.  To simplify descriptions of the
  193. X    automata, if no rule is present, the string will not be accepted. Also,
  194. X    the '.' character matches any character if it occurs first in the
  195. X    character list.
  196. X
  197. X
  198. X    Example 2: ^abc
  199. X
  200. X    <q0> a <q1>
  201. X    <q1> b <q2>
  202. X    <q2> c [q3]
  203. X    [q3] . [q3]
  204. X
  205. X
  206. X    Example 3: abc$
  207. X
  208. X    <q0> a <q1> . <q0>
  209. X    <q1> b <q2> a <q1> . <q0>
  210. X    <q2> c [q3] a <q1> . <q0>
  211. X    [q3] . <q1>
  212. X
  213. X
  214. X    Example 4: ^(abc)*$
  215. X
  216. X    [q0] a <q1>
  217. X    <q1> b <q2>
  218. X    <q2> c [q0]
  219. X
  220. X
  221. X    Example 5: ^[ab][cd][ef]$
  222. X
  223. X    <q0> ab <q1>
  224. X    <q1> cd <q2>
  225. X    <q2> ef [q3]
  226. X    [q3]
  227. X
  228. X
  229. X    Example 6: ^(abc|efg)$
  230. X
  231. X    <q0> a <q1> e <q3>
  232. X    <q1> b <q2>
  233. X    <q2> c [q5]
  234. X    <q3> f <q4>
  235. X    <q4> g [q5]
  236. X    [q5]
  237. X
  238. X
  239. X    With the automaton specification in 'filename', invoke the program by
  240. X    typing
  241. X
  242. X                                adgrep 'filename'
  243. X
  244. X    It will read stdin and print out all the lines which the automaton
  245. X    accepts.  If the file cannot be opened, a system error message will
  246. X    be printed.  If the input contains errors, then an error message along
  247. X    with the number of the offending line will be printed to stderr.  The 
  248. X    number of rules for each state is limited to 17.  If more than 17 rules 
  249. X    are present, you get the error to_many_rules, and the state that was 
  250. X    being processed is printed.  Error no_destination occurs if you specify a 
  251. X    set of characters, but no destination state, and error too_many_states 
  252. X    occurs if your automaton has more than 257 states.
  253. X
  254. X    Running
  255. X                             adgrep from < your_mailbox
  256. X
  257. X    will perform a function similar to that of the unix from command.
  258. X
  259. X    If no filename is specified on the command line, then "adgrep.c" is used
  260. X    as the specification for the automaton.  (This file has been renamed 
  261. X    to adrian.c by the judges.)  In this case, the program will search for 
  262. X    matches to the regular expression:
  263. X
  264. X                        ^.[^|C][^w[Q]*(Q|[w[]c).*|^.[C|]$
  265. X
  266. X    I suggest using adgrep.c as input, and storing the output in adwc.c:
  267. X
  268. X                           adgrep < adgrep.c > adwc.c
  269. X
  270. X    Compiling the new file, mywc.c, yields a clone of the unix wc command. It
  271. X    runs on one file (defaulting to "adgrep.c" if no file is given) and
  272. X    displays the number of lines, words, and bytes in the input file.
  273. X
  274. X
  275. X    Another possibly interesting automaton can be created by slightly
  276. X    adjusting the adgrep.c file.  Change the first line to read
  277. X
  278. X                                 /* . echo| . */
  279. X
  280. X    and repeat the process above
  281. X
  282. X                           adgrep <adgrep.c > adecho.c
  283. X
  284. X    The new file now contains all lines which match
  285. X
  286. X                      ^.[^5|m^]*[m^]([e=p,;]|[^e=+p,;].*)$
  287. X
  288. X    Compile and run.  This is an echo clone.  Note the efficient algorithm
  289. X    employed.
  290. X
  291. X
  292. X    Two other adjustments to the first line also yield useful results. By
  293. X    changing it to
  294. X                                 /* . head; . */
  295. X
  296. X    you can search for matches to
  297. X
  298. X                                  ^.[^W]*W..*$
  299. X
  300. X    By some freak happenstance, lines of adgrep.c which match this regular
  301. X    expression form a unix head command.  It prints the first ten lines of
  302. X    the file specified on the command line (or adgrep.c if no file is
  303. X    specified).
  304. X
  305. X    By setting the first line to
  306. X
  307. X                               /* . basename . */
  308. X
  309. X    a clone of the unix basename command can be unearthed. The automaton will
  310. X    search for
  311. X                                  ^.[^j]*jr.*$
  312. X
  313. X    on standard input.  And the program which results by running adgrep.c
  314. X    through this filter requires two parameters.  The first is meant to be a
  315. X    filename, and the second, an extension.  All leading pathname components
  316. X    are removed from the filename, and the extension is removed if present.
  317. X    The resulting base name is printed to stdout.
  318. X
  319. X    Lastly, by setting the first line to
  320. X
  321. X                                    /* . sleep . */
  322. X
  323. X    you can search for
  324. X
  325. X                        ^.[^(~][^s]*sl.*$
  326. X
  327. X    Filtering adgrep.c through this search yields a clone of the sleep
  328. X    command.  Invoke with a single integer parameter, and it will pause
  329. X    for that many seconds.
  330. X
  331. X    If either adbasename or adsleep is invoked with too few parameters,
  332. X    the program will print the error message:
  333. X                       Segmentation fault (core dumped)
  334. X
  335. X    (The exact text of the above error messages varies from machine to
  336. X    machine.)  The four programs which read from stdin require lines
  337. X    shorter than 999 characters.
  338. X
  339. X    The other info files are adrian.grep.[1-6] which contain the six
  340. X    examples that appear above, and from, which is used to emulate the
  341. X    unix from command.  For reasons of clarity, the name "from" should
  342. X    probably not be changed if possible.  I wouldn't want to be accused of 
  343. X    confusing people by giving the input files weird names.
  344. X
  345. X    If you want to change the default input filename (line 80) you must be
  346. X    careful to choose a name that doesn't match the wrong search patterns,
  347. X    introducing extra lines into one of the programs.
  348. X
  349. X    The program will produce at least one warning and possible several
  350. X    when compiled depending on the compiler.
  351. END_OF_FILE
  352.   if test 7292 -ne `wc -c <'1992/adrian.hint'`; then
  353.     echo shar: \"'1992/adrian.hint'\" unpacked with wrong size!
  354.   fi
  355.   # end of '1992/adrian.hint'
  356. fi
  357. if test -f '1992/adrian.orig.c' -a "${1}" != "-c" ; then 
  358.   echo shar: Will not clobber existing file \"'1992/adrian.orig.c'\"
  359. else
  360.   echo shar: Extracting \"'1992/adrian.orig.c'\" \(2581 characters\)
  361.   sed "s/^X//" >'1992/adrian.orig.c' <<'END_OF_FILE'
  362. X/* . wc . */
  363. X#include<stdio.h>/* Wht majr flwchrt? */
  364. X#include<string.h>/* That mjr flwchrt! */
  365. X#define P 257
  366. X#define G 17
  367. X#define z 8
  368. X#define v(jr) jr
  369. Xint W ,head;
  370. X#define S(W,b,f) strncpy(W,b,f),W[f]=0\
  371. X
  372. X  
  373. Xchar *wcs=" \t\n";
  374. Xstruct{ char X[z+1]; 
  375. X        char f ;
  376. X        int e ; 
  377. X        struct{ char g[z+1];
  378. X                int b ;
  379. X              } w[ G];
  380. X      } o[ P];
  381. Xint L=0,j= -28;
  382. X
  383. X
  384. Xvoid E(int i, int m,char*c)
  385. X{   
  386. X for(; i<43; i+=3) 
  387. X   putc(i["}|uutsrq`_^bji`[Zkediml[PO]a_M__]ISOYIRGTNR"]+i-9,stderr);
  388. X fprintf(stderr,"(%d): %s\n" ,m,c);
  389. X exit(1);
  390. X}
  391. X
  392. X
  393. X
  394. Xint N(int m, char *t)
  395. X{ 
  396. X  int i ;
  397. X  if (strlen ( 
  398. X              t)>z) t[z ]=0;
  399. X  for(i= 0; i< L ; i++) if(
  400. X                           !strcmp (o[ i] . X
  401. X                                             , t))return i;
  402. X  if( L== P)
  403. X             E(0, m, t);
  404. X  S (o[ L] . X , t
  405. X                  ,z);
  406. X  head; W = .1* head;
  407. X  o[L ].f = !( strchr( t,']' )== 0 );
  408. X  o[L ++ ] . e = 0;
  409. X  return L -1 ; }
  410. X
  411. X#define v(x )
  412. X
  413. Xint A(char *R)
  414. X{
  415. X  int c=0, i;
  416. X  while(* R) {
  417. X    i = -1;
  418. X    while(j){
  419. X      if( ++ i==o[ c].e ) return 0;
  420. X      if(o[ 
  421. X           c] .w[i ] .g[0 ] 
  422. X                            =='.' ||strchr (o[ c].w[i] .g ,* R)){
  423. X      c=
  424. X        o[ c ] .w[i].b; break;/*
  425. Xmain(int sl,char *j[]){
  426. X      sleep (~~~~~~~~atoi(j[1])) ;/* . sl
  427. X      sl s l . sl
  428. X      l l ]
  429. X      sl */ }
  430. X    }
  431. X    R++;
  432. X  }
  433. X  return o[ c].f;
  434. X}
  435. X
  436. X
  437. X main(int wc,char *V[]){char Y[999],*s;FILE*W;int m=0,echo,jr,q,wcl=0,wcw=0,wcc=0;
  438. X v(s = V[1]; if (*V=strrchr(s,'/'))s=*V+1;  if(( !strncmp( s + (jr=strlen(s)) -
  439. X  (q=strlen(V[2]) ),V[2],q))&&jr!=q) s[jr-q] = 0;  puts(s); )
  440. X int e,p,C,Q ,basename;
  441. X W= fopen(wc>= 2 ? V[1] : "adgrep.c","rt");
  442. Xecho| m^ e| 5| (int) .8| echo|
  443. Xwc |C ==o[o[C] .e] . 
  444. Xe| e==+p,p; s[o[C] .e ] 
  445. X;
  446. Xwhile( fgets(Y,998,W)) { wcc += strlen(Y); m++;
  447. X     if( s = strtok(Y,wcs)) wcw++;
  448. X     else continue ;
  449. X     C=
  450. X       basename= j +j+*"* . basename" 
  451. X                +j+*"* r ] " + N(m,s) ;
  452. Xwhile( s = strtok(0,wcs)) {
  453. X       if( o[ C ] . e == 
  454. X                         G) E(1 ,m,o[C] .X) ;
  455. X       S(o[C
  456. X             ] .w[o[C ] .e].g,s, z);
  457. X       Q= C ;
  458. X       if(! ( s =strtok ( 0 ,wcs )))wcw --
  459. X       ,E( 2 , m, o[C]
  460. X                   . w[ o[ Q ] .e] . g );
  461. X       e
  462. X         = o[C ] .w[o[C ] .e++ ] .b= N(m,s)
  463. X       ; wcw += 2; }  
  464. X     0&& 
  465. X        W && wcl++
  466. X                  < 10 && printf((W,Y)); }
  467. X   if(j+28) { {
  468. X                ; } printf("%7u%7u%7u\n", wcl , wcw , wcc); }
  469. X   while( gets(Y) ) if(A(Y)) puts(Y);
  470. X   W, jr; }
  471. X
  472. XO(int wc,char**V) {
  473. X--wc && (printf("%s ",*++V), main(wc,V), 1) || printf("\n"); }
  474. X
  475. END_OF_FILE
  476.   if test 2581 -ne `wc -c <'1992/adrian.orig.c'`; then
  477.     echo shar: \"'1992/adrian.orig.c'\" unpacked with wrong size!
  478.   fi
  479.   # end of '1992/adrian.orig.c'
  480. fi
  481. if test -f '1992/albert.orig.c' -a "${1}" != "-c" ; then 
  482.   echo shar: Will not clobber existing file \"'1992/albert.orig.c'\"
  483. else
  484.   echo shar: Extracting \"'1992/albert.orig.c'\" \(3153 characters\)
  485.   sed "s/^X//" >'1992/albert.orig.c' <<'END_OF_FILE'
  486. X#include <stdio.h>
  487. X#include <malloc.h>
  488. X#include <setjmp.h>
  489. X#include <ctype.h>
  490. X#define new(PP) (PP *) malloc(sizeof(PP)) 
  491. Xtypedef struct q {
  492. X    jmp_buf ppp;
  493. X    long qq;
  494. X    struct q *P;
  495. X    struct q *p;
  496. X} 
  497. XPP;
  498. X
  499. XPP *P;
  500. Xint aaaaaa=2;
  501. Xint aaaaaaa=1;
  502. X
  503. Xlong qqq;
  504. X
  505. X
  506. XaaAaaa(aa,aaa)
  507. Xchar *aa;
  508. Xchar *aaa;
  509. X{
  510. X    char aaaa = 0;
  511. X    if ((((( aaa )))))
  512. X    {
  513. X        aaaa = *aa;
  514. X        *aa=0;
  515. X        aa+=strlen(aa+1);
  516. X        P =new(PP);
  517. X        P->P=P;
  518. X        P->p=P;
  519. X    }
  520. X
  521. X    if ((((( !setjmp(P->ppp) ))))) 
  522. X        {
  523. X        if ((((( !isdigit(*aa) )))))
  524. X            longjmp(P->ppp,aaaaaaa);
  525. X        else {
  526. X            P->p->P = new(PP);
  527. X            P->p->P->P = P;
  528. X            P->p->P->p = P->p;
  529. X            P->p = P->p->P;
  530. X
  531. X            P->qq = *aa--;
  532. X            P = P->p;
  533. X            aaAaaa(aa,0);
  534. X        }
  535. X    } else {
  536. X        if ( !aaaa&&!*aa ) 
  537. X           longjmp(P->p->ppp,aaaaaaa);
  538. X
  539. X        if ((((( (P->qq=aaaa)<10     &&!
  540. X                 (isdigit(aaaa))     ||!
  541. X                 (isdigit(*aa)       ||!
  542. X                 *aa                        )))))) 
  543. X        {
  544. X            fprintf(stderr,"Usage %c%s <number>\n",
  545. X            (aaa[0]?7:aaaa),aaa+!aaa[0]);
  546. X            exit(1);
  547. X        }
  548. X    }
  549. X}
  550. X
  551. X
  552. XppPppp(pp,ppp)
  553. XPP **pp, *ppp;
  554. X{
  555. X    int aa;
  556. X    if ((((( !(aa=setjmp(ppp->ppp))||aa==aaaaaa )))))
  557. X    {
  558. X        if ((((( *pp==ppp )))))
  559. X        {
  560. X            ppp = (*pp)->p;
  561. X
  562. X            if ( qqq<47 ) return;
  563. X            if ( ppp->qq!=48 ) return;
  564. X
  565. X            while ( ppp->qq==48 ) 
  566. X            {
  567. X                printf("%ld\n",qqq-45);
  568. X                *pp = ppp;
  569. X                ppp = ppp->p;
  570. X            }
  571. X            qqq -= 1;
  572. X            longjmp(ppp->ppp,aaaaaaa);
  573. X        } else {
  574. X            PP *p;
  575. X
  576. X            ppPppp(pp,ppp->p);
  577. X            for (p=ppp;p!=*pp;p=p->p)
  578. X            {
  579. X                int qq=4;
  580. X                if ((((( qqq<47                            &&
  581. X                         (qq=0,p->qq+=p->p->qq-96)>=48-qqq ||
  582. X                         qqq>46                            &&
  583. X                         (p->qq-=p->p->qq)<0                   ))))) 
  584. X                {
  585. X                    p->qq += qqq+qq;
  586. X                    if ( p->p==P && qqq<=46 )
  587. X                    {
  588. X                        P->p->P = new(PP);
  589. X                        P->p->P->P = P;
  590. X                        P->p->P->p = P->p;
  591. X                        *pp = P = P->p = P->p->P;
  592. X                        P->qq = 48;
  593. X                    }
  594. X
  595. X                    p->p->qq+=qq==0;
  596. X                    p->p->qq-=qq!=0;
  597. X                }
  598. X                else
  599. X                {
  600. X                    p->qq += 48;
  601. X                }
  602. X            }
  603. X            if ( ppp->P==P ) longjmp(ppp->ppp,aaaaaaa);
  604. X        }
  605. X    }
  606. X    else
  607. X    {
  608. X        qqq += 1; 
  609. X
  610. X        while (48==P->qq )
  611. X        {
  612. X            P->P->p = P->p;
  613. X            P = P->p->P = P->P;
  614. X
  615. X        }
  616. X
  617. X        if (ppp!=ppp->p->p )
  618. X            longjmp(ppp->ppp,aaaaaa);
  619. X        else
  620. X        {
  621. X            printf("At most one remains\n");
  622. X            exit(0);
  623. X        }
  624. X    }
  625. X}
  626. X
  627. X
  628. Xmain(aaa,aaaa)
  629. Xint aaa;
  630. Xchar **aaaa;
  631. X{
  632. X    aaAaaa(aaa==aaaaaaa?aaaa[0]:aaaa[1],aaaa[0]);
  633. X    qqq = 39;
  634. X    ppPppp(&P,P->p);
  635. X}
  636. X
  637. X
  638. END_OF_FILE
  639.   if test 3153 -ne `wc -c <'1992/albert.orig.c'`; then
  640.     echo shar: \"'1992/albert.orig.c'\" unpacked with wrong size!
  641.   fi
  642.   # end of '1992/albert.orig.c'
  643. fi
  644. if test -f '1992/imc.hint' -a "${1}" != "-c" ; then 
  645.   echo shar: Will not clobber existing file \"'1992/imc.hint'\"
  646. else
  647.   echo shar: Extracting \"'1992/imc.hint'\" \(6479 characters\)
  648.   sed "s/^X//" >'1992/imc.hint' <<'END_OF_FILE'
  649. XBest Output: <imc@ecs.ox.ac.uk> Ian Collier
  650. X
  651. X    Ian Collier
  652. X    Oxford University
  653. X    The Queen's College
  654. X    High Street
  655. X    OXFORD
  656. X    OX1 4AW
  657. X    ENGLAND
  658. X
  659. X
  660. XJudges' comments:
  661. X
  662. X    Make and run.
  663. X
  664. X    The program is more interesting to run on workstations that can
  665. X    make use of a Sun raster file.  Others can make use of the -text
  666. X    flag for character oriented output.
  667. X
  668. X    Of course, the source (layout) is self-documenting!  :-)
  669. X
  670. X    NOTE: The original winning source imc.orig.c assumed that
  671. X      exit returned a value which cause problems for some
  672. X      systems where exit returned a void.  The file imc.c
  673. X      avoids this problem.
  674. X
  675. X
  676. XSelected notes from the author:
  677. X
  678. X    Portability
  679. X
  680. X    This program depends upon the ASCII character set, and makes certain
  681. X    assumptions about the architecture. It naughtily declares the first
  682. X    argument to main as a long, and passes a pointer to long instead of char
  683. X    to fwrite, giving a length value of 32 bytes for an array of 8 longs. I
  684. X    guess that makes this program OK on most flavours of unix, but not on
  685. X    PCs.
  686. X
  687. X    About the program
  688. X
  689. X    This program has several parameters; each of them has a default, so the
  690. X    program runs happily without any parameters. If you supply an incorrect
  691. X    parameter, an obfuscated error message results! :-) Should you want to
  692. X    run the program without knowing what it does, then supplying the single
  693. X    letter t as a parameter is a good move. Otherwise, direct the output
  694. X    into a file. The resulting file is most useful on Sun OS, where the
  695. X    "file" command will tell you what to do with it. For best results with
  696. X    the t option, you may want to change the definition of the I macro :-)
  697. X    Details appear later, though the formatting of the code is a large clue.
  698. X
  699. X    All the code in this program appears between the ";" and ")" in
  700. X    "for(;;)". That isn't because I want to win the best one-liner, but
  701. X    merely because it makes the code so much more impenetrable :-) In fact
  702. X    running a pretty printer on the code hardly improves it at all. This
  703. X    program has the obligatory macros with unmatched parentheses, and the
  704. X    cleverly arranged macro names and parameters to spell out "Ian Colliers
  705. X    Obfuscated C Code". If you expand macros, bear in mind that the more
  706. X    complex ones are best left as macros, because they have well-defined and
  707. X    nontrivial (IMHO) functions. These macros help to give the program's
  708. X    parameter format its flexibility. The parameters are sorted out in a
  709. X    unique way (based on an idea by Pete Bevin) which hides very effectively
  710. X    their identities (and I think that using a variable called _ adds a nice
  711. X    touch to the illegibility of the code). In this section of the code, the
  712. X    data types of the numbers checked against is varied, and just because
  713. X    you see a ',' doesn't mean it has anything to do with commas! So I hope
  714. X    you will agree that this program is more than a little obfuscated...
  715. X
  716. X    This is a Mandelbrot/Julia drawer. Normally it produces a monochrome
  717. X    Sun-format raster file. The version of xloadimage we have is able to
  718. X    view such files, and so is Sun's screenload command. [Note: the header
  719. X    contains eight 4-byte integers, the byte order in which depends upon the
  720. X    machine. On Sun workstations they are stored MSB first].
  721. X
  722. X    The program may be asked to produce text output instead of a raster
  723. X    file. Then the characters defined in the I macro will be used to create
  724. X    up to 16 different shades of grey. Quite a respectable picture can be
  725. X    gained by printing a 130x110 output on a dot matrix 132 column printer
  726. X    with the linefeed set to 7 points. Text output also gives a good picture
  727. X    when used in an X window with small characters having a square aspect
  728. X    ratio.
  729. X
  730. X    The options accepted by the program follow. Each option is a letter; it
  731. X    may be preceded with a minus sign (or any character in [!-/]) and may be
  732. X    followed by other letters, so for example
  733. X          m    -m     mask     *mail
  734. X    all mean the same thing. Most options may be followed by one or two
  735. X    numbers. These numbers may be separated from each other and from the
  736. X    option by a space, or may be joined to each other with a comma, or may
  737. X    be appended to the single-letter option, so
  738. X          -s100,200    size 100,200    -size123 100 200  s100 200
  739. X    all mean the same (note that in "-size123" all characters following the
  740. X    initial s are ignored). Numbers need not be specified, as each has a
  741. X    default value. In all cases except "j" and "t", and "s" whenever it
  742. X    appears before "t", specifying an option without numbers has no effect.
  743. X    (specifying "-s -t" has the effect of producing text with the default
  744. X    raster size; not a good idea!). The options are:
  745. X
  746. X    -centre x y  (float x,y) Centre the picture at x+iy in the complex
  747. X                             plane (default x=0 y=0)
  748. X    -factor f    (float f)   Use f pixels per unit of the plane (default
  749. X                             f=x/4 where x is the width)
  750. X    -julia  x y  (float x,y) Draw a julia set. Use x+iy as the constant
  751. X                             to add after squaring (default x=0 y=0)
  752. X    -limit  l    (int l)     Use l iterations maximum (default l=128)
  753. X    -mask   m    (int m)     Use m as a mask in deciding the colour of each
  754. X                             pixel (see below) (default m=1)
  755. X    -size   x y  (int x,y)   Produce an x-by-y output (default for raster
  756. X                             x=768 y=768; default for text x=63 y=23)
  757. X    -text                    Produce text instead of raster.
  758. X
  759. X    The colour of each point is determined by taking the bit-and of the
  760. X    number of iterations and the mask. For a raster, the point is black
  761. X    (1-bit) if the result is zero, white otherwise. For text, the result of
  762. X    the operation determines the grey-ness of the character produced, with a
  763. X    blank for zero going up to a star for the maximum value. For a
  764. X    four-colour picture, for example, use a mask with two bits set (e.g. 3),
  765. X    and for a 16-colour picture use a mask with four bits set (e.g. 15). For
  766. X    a picture with coarse detail, use a mask which ends with several zero
  767. X    bits (e.g. 8).
  768. X
  769. X    While the program is creating your picture, it displays dots on the
  770. X    standard error to indicate its progess (one dot per pixel line).
  771. X
  772. X    Here are a couple of good pictures to draw:
  773. X
  774. X    imc -s 512,512 -f 600000 -l 512 -m 16 -c.00805,.74274 > screen1.ras
  775. X    imc -s512,512 -j-.523,-.535 > screen2.ras
  776. END_OF_FILE
  777.   if test 6479 -ne `wc -c <'1992/imc.hint'`; then
  778.     echo shar: \"'1992/imc.hint'\" unpacked with wrong size!
  779.   fi
  780.   # end of '1992/imc.hint'
  781. fi
  782. if test -f '1992/nathan.hint' -a "${1}" != "-c" ; then 
  783.   echo shar: Will not clobber existing file \"'1992/nathan.hint'\"
  784. else
  785.   echo shar: Extracting \"'1992/nathan.hint'\" \(4546 characters\)
  786.   sed "s/^X//" >'1992/nathan.hint' <<'END_OF_FILE'
  787. XWorst Abuse of the Rules: <nathan@inmos.co.uk> Nathan Sidwell
  788. X
  789. X    Nathan Sidwell
  790. X    Inmos UK
  791. X    1000 Aztec West
  792. X    Almondsbury
  793. X    Bristol
  794. X    UK BS12 4SQ
  795. X
  796. X
  797. XJudges' comments:
  798. X
  799. X    The US International Traffic in Arms Regulations controls certain
  800. X    exportations going out of the United States.  The U.S.  Munitions
  801. X    List gives the specific categories of restricted exports.  Because
  802. X    this entry appears to fall under this restricted catagory, the
  803. X    judges may not be able to distribute winners outside of the USA.
  804. X
  805. X    Nathan Sidwell has stated that he is willing to distribute the
  806. X    winning source.  To read HIS instructions of how to obtain his
  807. X    winning program:
  808. X
  809. X    make nathan
  810. X    nathan
  811. X
  812. X    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  813. X    =-=-= The text below assumes that you have the winning source =-=-=
  814. X    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  815. X
  816. X    To use:
  817. X    make nathan
  818. X
  819. X    Try:
  820. X    nathan obfuscate < nathan.c > foobarf.c
  821. X    nathan - obfuscate < foobarf.c > barfoof.c
  822. X    diff nathan.c barfoof.c
  823. X
  824. X    WARNING:
  825. X    The judges' make no claim as to the strength or security
  826. X    of this program.  It is likely to be nil, or the next
  827. X    best thing to it.  Still, you might consider installing
  828. X    it in /usr/games/nathan.  :-)
  829. X
  830. X    NOTE: 
  831. X    The 'winning' catagory is also open to question.  One could say
  832. X    that it is a 'file obfuscator'.  One could also say that it
  833. X    unintentionally adbused the intent of rule #7 (that programs
  834. X    should be freely redistributable).  We suspect that the author
  835. X    may not have intended to do this, but that is the way things go
  836. X    sometimes.
  837. X
  838. X    BTW, 'abuse of the rules' entries do not violate the rules.
  839. X    Entries that violate the rules are disqualified.  Abuse of the
  840. X    rules entries are ones that tend to 'streach' the limits and
  841. X    take the contest into unexpected territory.
  842. X
  843. X
  844. XPersonal note from chongo:
  845. X
  846. X    I think this situation shows just how ridiculous US crypto
  847. X    regulations really are.  Certain US federal officials can get away
  848. X    with shipping arms to certain nations in apparent violation of US
  849. X    laws, but I personally can't re-distribute a program contest winner
  850. X    to the network!
  851. X
  852. X
  853. XSelected notes from the author:
  854. X
  855. X    PROGRAM USE
  856. X
  857. X    This program is a hello world text encrypter/decrypter. It uses an
  858. X    enigma (I think) style encryption algorithm, where the encryption
  859. X    key character is modified by a value, determined from the previous
  860. X    character.  Non-printable characters (those with ASCII values < ' '
  861. X    or > 0x7e) are passed unaltered, thus any kind of file may be
  862. X    successfully procesed, but if the original is printable, the
  863. X    processed file will be too. The input is read from stdin, and the
  864. X    output presented to stdout. The key, a text string, is presented as
  865. X    a command argument. This is optional, and if ommitted, the file is
  866. X    self-{de,en}crypted. To specify decryption, a "-" should be given
  867. X    before the key. (Actually encryption and dycryption proper inverse
  868. X    operations, so you can use decrypt to scramble and encrypt to
  869. X    descramble, if you're perverse.)
  870. X
  871. X    PORTABILITY (A little knowledge is a dangerous thing)
  872. X
  873. X    Its written in ANSI C, and doesn't even assume an ASCII character
  874. X    set, (it has an array of the characters to convert), so should be
  875. X    portable across many platforms. It passes gcc -ansi -pedantic -O
  876. X    -Wall with no warnings (You may get assignment in conditional
  877. X    warnings on other platforms though).  Because I've heard that
  878. X    conditional jumps slow down fast processors, I've eliminated all
  879. X    the ifs from the code, indeed, as its only one statement, it should
  880. X    compile to one instruction an a suitably designed CISC machine. To
  881. X    speed compilation, there is only one statement in the loop, so that
  882. X    another scoping level does not need to be opened.
  883. X
  884. X    Being an encrypter/decrypter, you probably want the source code to
  885. X    be obfuscated, to hide the algorithm.
  886. X
  887. X    OBFUSCATION
  888. X
  889. X    Inspite of the fact that it looks like a nice friendly hello world
  890. X    program, it isn't (as documented above). (Short lines have been padded,
  891. X    as you'll find if you look at an encrypted copy of the source.)
  892. X
  893. X    I've also named some of the macros from commonly used functions,
  894. X    just to keep things muddy. Of course, all the variables are
  895. X    misnamed. The program is kept simply (one for statement), by
  896. X    serious overuse of , and ? :. These are really confusing when used
  897. X    together, nested or put in argument lists (is that a comma
  898. X    operator, or argument separator?)
  899. END_OF_FILE
  900.   if test 4546 -ne `wc -c <'1992/nathan.hint'`; then
  901.     echo shar: \"'1992/nathan.hint'\" unpacked with wrong size!
  902.   fi
  903.   # end of '1992/nathan.hint'
  904. fi
  905. if test -f '1992/third' -a "${1}" != "-c" ; then 
  906.   echo shar: Will not clobber existing file \"'1992/third'\"
  907. else
  908.   echo shar: Extracting \"'1992/third'\" \(6605 characters\)
  909.   sed "s/^X//" >'1992/third' <<'END_OF_FILE'
  910. X: immediate _read @ ! - * / <0 exit echo key _pick
  911. X
  912. X: debug immediate 1 5 ! exit
  913. X
  914. X: r 1 exit
  915. X
  916. X: ] r @ 1 - r ! _read ]
  917. X
  918. X: _main immediate r @ 7 ! ]
  919. X_main
  920. X
  921. X
  922. X: _x 3 @ exit
  923. X: _y 4 @ exit
  924. X: _x! 3 ! exit
  925. X: _y! 4 ! exit
  926. X
  927. X
  928. X: swap _x! _y! _x _y exit
  929. X
  930. X: + 0 swap - - exit
  931. X
  932. X: dup _x! _x _x exit
  933. X
  934. X: inc dup @ 1 + swap ! exit
  935. X
  936. X: h 0 exit
  937. X
  938. X: , h @ ! h inc exit
  939. X
  940. X
  941. X: ' r @ @ dup 1 + r @ ! @ exit
  942. X
  943. X: ; immediate ' exit , exit
  944. X
  945. X
  946. X: drop 0 * + ;
  947. X
  948. X: dec dup @ 1 - swap ! ;
  949. X
  950. X: tor r @ @ swap r @ ! r @ 1 + r ! r @ ! ;
  951. X
  952. X: fromr r @ @ r @ 1 - r ! r @ @ swap r @ ! ;
  953. X
  954. X: tail fromr fromr drop tor ;
  955. X
  956. X: minus 0 swap - ;
  957. X
  958. X: bnot 1 swap - ;
  959. X
  960. X: < - <0 ;
  961. X
  962. X: logical dup 0 < swap minus 0 < + ;
  963. X
  964. X: not logical bnot ;
  965. X
  966. X: = - not ;
  967. X
  968. X: branch r @ @ @ r @ @ + r @ ! ;
  969. X
  970. X: computebranch 1 - * 1 + ;
  971. X
  972. X: notbranch
  973. X  not
  974. X  r @ @ @
  975. X  computebranch
  976. X  r @ @ +
  977. X  r @ !
  978. X;
  979. X
  980. X: here h @ ;
  981. X
  982. X: if immediate ' notbranch , here 0 , ;
  983. X
  984. X: then immediate dup here swap - swap ! ;
  985. X
  986. X: ')' 0 ;
  987. X
  988. X: _fix key drop key swap 2 + ! ;
  989. X
  990. X: fix-')' immediate ' ')' _fix ;
  991. X
  992. Xfix-')' )
  993. X
  994. X: find-) key ')' = not if tail find-) then ;
  995. X
  996. X: ( immediate find-) ;
  997. X
  998. X( we should be able to do FORTH-style comments now )
  999. X
  1000. X( this works as follows: ( is an immediate word, so it gets
  1001. X  control during compilation.  Then it simply reads in characters
  1002. X  until it sees a close parenthesis.  once it does, it exits.
  1003. X  if not, it pops off the return stack--manual tail recursion. )
  1004. X
  1005. X( now that we've got comments, we can comment the rest of the code! )
  1006. X
  1007. X: else immediate
  1008. X  ' branch ,        ( compile a definite branch )
  1009. X  here            ( push the backpatching address )
  1010. X  0 ,            ( compile a dummy offset for branch )
  1011. X  swap            ( bring old backpatch address to top )
  1012. X  dup here swap -    ( calculate the offset from old address )
  1013. X  swap !        ( put the address on top and store it )
  1014. X;
  1015. X
  1016. X: over _x! _y! _y _x _y ;
  1017. X
  1018. X: add
  1019. X  _x!            ( save the pointer in a temp variable )
  1020. X  _x @            ( get the value pointed to )
  1021. X  +            ( add the incremement from on top of the stack )
  1022. X  _x !            ( and save it )
  1023. X;
  1024. X
  1025. X: allot    h add ;
  1026. X
  1027. X: maybebranch
  1028. X  logical        ( force the TOS to be 0 or 1 )
  1029. X  r @ @ @        ( load the branch offset )
  1030. X  computebranch    ( calculate the condition offset [either TOS or 1])
  1031. X  r @ @ +        ( add it to the return address )
  1032. X  r @ !        ( store it to our return address and return )
  1033. X;
  1034. X
  1035. X: mod _x! _y!        ( get x then y off of stack )
  1036. X  _y
  1037. X  _y _x / _x *        ( y - y / x * x )
  1038. X  -
  1039. X;
  1040. X
  1041. X: '\n' 0 ;
  1042. X: '"' 0 ;
  1043. X: '0' 0 ;
  1044. X: 'space' 0 ;
  1045. X
  1046. X: fix-'\n' immediate ' '\n' _fix ;
  1047. X: fix-'"' immediate ' '"' _fix ;
  1048. X: fix-'0' immediate ' '0' _fix ;
  1049. X: fix-'space' immediate ' 'space' _fix ;
  1050. X
  1051. Xfix-'0' 0 fix-'space'  fix-'"' "
  1052. Xfix-'\n'
  1053. X
  1054. X
  1055. X: cr '\n' echo exit
  1056. X
  1057. X: printnum
  1058. X  dup
  1059. X  10 mod '0' +
  1060. X  swap 10 / dup
  1061. X  if
  1062. X    printnum 0
  1063. X  then
  1064. X  drop echo
  1065. X;
  1066. X
  1067. X: .
  1068. X  dup 0 <
  1069. X  if
  1070. X    45 echo minus
  1071. X  then
  1072. X  printnum
  1073. X  'space' echo
  1074. X;
  1075. X
  1076. X
  1077. X: debugprint dup . cr ;
  1078. X
  1079. X( the following routine takes a pointer to a string, and prints it,
  1080. X  except for the trailing quote.  returns a pointer to the next word
  1081. X  after the trailing quote )
  1082. X
  1083. X: _print
  1084. X  dup 1 +
  1085. X  swap @
  1086. X  dup '"' =
  1087. X  if
  1088. X    drop exit
  1089. X  then
  1090. X  echo
  1091. X  tail _print
  1092. X;
  1093. X
  1094. X: print _print ;
  1095. X
  1096. X  ( print the next thing from the instruction stream )
  1097. X: immprint
  1098. X  r @ @
  1099. X  print
  1100. X  r @ !
  1101. X;
  1102. X
  1103. X: find-"
  1104. X  key dup ,
  1105. X  '"' =
  1106. X  if
  1107. X    exit
  1108. X  then
  1109. X  tail find-"
  1110. X;
  1111. X
  1112. X: " immediate
  1113. X  key drop
  1114. X  ' immprint ,
  1115. X  find-"
  1116. X;
  1117. X
  1118. X: do immediate
  1119. X  ' swap ,        ( compile 'swap' to swap the limit and start )
  1120. X  ' tor ,        ( compile to push the limit onto the return stack )
  1121. X  ' tor ,        ( compile to push the start on the return stack )
  1122. X  here            ( save this address so we can branch back to it )
  1123. X;
  1124. X
  1125. X: i r @ 1 - @ ;
  1126. X: j r @ 3 - @ ;
  1127. X
  1128. X: > swap < ;
  1129. X: <= 1 + < ;
  1130. X: >= swap <= ;
  1131. X
  1132. X: inci 
  1133. X  r @ 1 -     ( get the pointer to i )
  1134. X  inc        ( add one to it )
  1135. X  r @ 1 - @     ( find the value again )
  1136. X  r @ 2 - @    ( find the limit value )
  1137. X  <
  1138. X  if
  1139. X    r @ @ @ r @ @ + r @ ! exit        ( branch )
  1140. X  then
  1141. X  fromr 1 +
  1142. X  fromr drop
  1143. X  fromr drop
  1144. X  tor
  1145. X;
  1146. X      
  1147. X: loop immediate ' inci , here - , ;
  1148. X
  1149. X: loopexit
  1150. X
  1151. X  fromr drop        ( pop off our return address )
  1152. X  fromr drop        ( pop off i )
  1153. X  fromr drop        ( pop off the limit of i )
  1154. X;            ( and return to the caller's caller routine )
  1155. X
  1156. X: isprime
  1157. X  dup 2 = if
  1158. X    exit
  1159. X  then
  1160. X  dup 2 / 2        ( loop from 2 to n/2 )
  1161. X  do
  1162. X    dup            ( value we're checking if it's prime )
  1163. X    i mod        ( mod it by divisor )
  1164. X    not if
  1165. X      drop 0 loopexit    ( exit from routine from inside loop )
  1166. X    then
  1167. X  loop 
  1168. X;
  1169. X
  1170. X: primes
  1171. X  " The primes from "
  1172. X  dup .
  1173. X  "  to "
  1174. X  over .
  1175. X  "  are:"
  1176. X  cr
  1177. X
  1178. X  do
  1179. X    i isprime 
  1180. X    if
  1181. X      i . 'space' echo
  1182. X    then
  1183. X  loop
  1184. X  cr
  1185. X;
  1186. X
  1187. X: execute
  1188. X  8 !
  1189. X  ' exit 9 !
  1190. X  8 tor
  1191. X;
  1192. X
  1193. X: :: ;        ( :: is going to be a word that does ':' at runtime )
  1194. X
  1195. X: fix-:: immediate 3 ' :: ! ;
  1196. Xfix-::
  1197. X
  1198. X    ( Override old definition of ':' with a new one that invokes ] )
  1199. X: : immediate :: ] ;
  1200. X
  1201. X: command
  1202. X  here 5 !        ( store dict pointer in temp variable )
  1203. X  _read            ( compile a word )
  1204. X            ( if we get control back: )
  1205. X  here 5 @
  1206. X  = if
  1207. X    tail command    ( we didn't compile anything )
  1208. X  then
  1209. X  here 1 - h !        ( decrement the dictionary pointer )
  1210. X  here 5 @        ( get the original value )
  1211. X  = if
  1212. X    here @        ( get the word that was compiled )
  1213. X    execute        ( and run it )
  1214. X  else
  1215. X    here @        ( else it was an integer constant, so push it )
  1216. X    here 1 - h !    ( and decrement the dictionary pointer again )
  1217. X  then
  1218. X  tail command
  1219. X;
  1220. X
  1221. X: make-immediate    ( make a word just compiled immediate )
  1222. X  here 1 -        ( back up a word in the dictionary )
  1223. X  dup dup        ( save the pointer to here )
  1224. X  h !            ( store as the current dictionary pointer )
  1225. X  @            ( get the run-time code pointer )
  1226. X  swap            ( get the dict pointer again )
  1227. X  1 -            ( point to the compile-time code pointer )
  1228. X  !            ( write run-time code pointer on compile-time pointer )
  1229. X;
  1230. X
  1231. X: <build immediate
  1232. X  make-immediate    ( make the word compiled so far immediate )
  1233. X  ' :: ,        ( compile '::', so we read next word )
  1234. X  2 ,            ( compile 'pushint' )
  1235. X  here 0 ,        ( write out a 0 but save address for does> )
  1236. X  ' , ,            ( compile a push that address onto dictionary )
  1237. X;
  1238. X
  1239. X: does> immediate
  1240. X  ' command ,        ( jump back into command mode at runtime )
  1241. X  here swap !        ( backpatch the build> to point to here )
  1242. X  2 ,            ( compile run-code primitive so we look like a word )
  1243. X  ' fromr ,        ( compile fromr, which leaves var address on stack )
  1244. X;
  1245. X
  1246. X
  1247. X: _dump            ( dump out the definition of a word, sort of )
  1248. X  dup " (" . " , "
  1249. X  dup @            ( save the pointer and get the contents )
  1250. X  dup ' exit
  1251. X  = if
  1252. X    " ;)" cr exit
  1253. X  then
  1254. X  . " ), "
  1255. X  1 +
  1256. X  tail _dump
  1257. X;
  1258. X
  1259. X: dump _dump ;
  1260. X
  1261. X: # . cr ;
  1262. X  
  1263. X: var <build , does> ;
  1264. X: constant <build , does> @ ;
  1265. X: array <build allot does> + ;
  1266. X
  1267. X: [ immediate command ;
  1268. X: _welcome " Welcome to THIRD.
  1269. XOk.
  1270. X" ;
  1271. X
  1272. X: ; immediate ' exit , command exit
  1273. X
  1274. X[
  1275. X
  1276. X_welcome
  1277. END_OF_FILE
  1278.   if test 6605 -ne `wc -c <'1992/third'`; then
  1279.     echo shar: \"'1992/third'\" unpacked with wrong size!
  1280.   fi
  1281.   # end of '1992/third'
  1282. fi
  1283. if test -f '1992/vern.hint' -a "${1}" != "-c" ; then 
  1284.   echo shar: Will not clobber existing file \"'1992/vern.hint'\"
  1285. else
  1286.   echo shar: Extracting \"'1992/vern.hint'\" \(6513 characters\)
  1287.   sed "s/^X//" >'1992/vern.hint' <<'END_OF_FILE'
  1288. XBest of Show: <vern@ee.lbl.gov> Vern Paxson
  1289. X
  1290. X    Vern Paxson
  1291. X    Lawrence Berkeley Laboratory
  1292. X    Computer Systems Engineering
  1293. X    Bldg. 46A, Room 1123
  1294. X    Lawrence Berkeley Laboratory
  1295. X    1 Cyclotron Rd.
  1296. X    Berkeley, CA 94720  USA
  1297. X
  1298. X
  1299. XJudges' comments:
  1300. X
  1301. X     Try: 
  1302. X    make vern
  1303. X    vern 3        <-- default is 2
  1304. X
  1305. X     You might start off by giving the following input:
  1306. X    63 43
  1307. X    76 55
  1308. X    71 52
  1309. X    67 57        (this may take a while)
  1310. X    
  1311. X    The judges assume no responsibility for the obfuscated opening
  1312. X    suggested above.  :-)
  1313. X
  1314. X    For a real quick game try:
  1315. X    vern
  1316. X
  1317. X    65 55
  1318. X    66 46
  1319. X
  1320. X    NOTE: Move values must be restricted to the range 00 to 77.
  1321. X
  1322. X    NOTE: Because some mailers have problems with the original winning source,
  1323. X      a slightly modified version with shorter lines has been provided.
  1324. X
  1325. X
  1326. XSelected notes from the author:
  1327. X
  1328. X    This program plays chess.  You play the white pieces and the program
  1329. X    the black pieces.  Moves are entered as a two-digit number specifying
  1330. X    the coordinates of the piece to be moved followed by another two-digit
  1331. X    number specifying the coordinates of where to move it.  Rows and
  1332. X    columns are numbered starting with (0,0) for the upper-lefthand corner
  1333. X    (black's queen's rook) and going to (7,7) for the lower-righthand
  1334. X    corner (white's king's rook).  For example, the PK4 opening for white
  1335. X    is indicated as "64 44".  Moves are read using scanf() so care should
  1336. X    be taken to not enter the wrong number of fields.
  1337. X
  1338. X    If the move you enter is illegal then you are just prompted again to
  1339. X    move.  If the move is legal then the new position is displayed and the
  1340. X    program starts computing its response.  For every 64 board positions it
  1341. X    examines a "." is printed.  Once it has chosen its move it simply
  1342. X    displays the board updated to reflect the move.
  1343. X
  1344. X    Your move is prompted for using a string like "1351 9 2 >".  The first
  1345. X    number is how many board positions the program examined when computing
  1346. X    its previous response.  The second number is its anticipated value for
  1347. X    the move it just made (with larger numbers meaning an ultimately better
  1348. X    board position for it), and the third number is the evaluation it
  1349. X    assigns to the your current position (larger numbers meaning better
  1350. X    positions for you).  A ">" indicates that you are not in check; for
  1351. X    check it is changed to "!".
  1352. X
  1353. X    There are a few limitations on play:
  1354. X
  1355. X    o        castling can only be done on the king's side;
  1356. X    o        prohibitions against castling out of or through check are
  1357. X             not enforced;
  1358. X    o        prohibitions against castling if the king or rook have moved
  1359. X             are not enforced;
  1360. X    o        pawns are always promoted to queens;
  1361. X    o        en passant is not allowed;
  1362. X    o        the board-position-repeated-three-times and fifty-moves
  1363. X             stalemates are not recognized;
  1364. X
  1365. X    If you checkmate the computer it prints "Rats!" and exits.  If your own
  1366. X    checkmate is imminent it prints "Har har." but doesn't exit so it can
  1367. X    rub your nose in defeat (which may be a move or two away if you're
  1368. X    playing at a high "ply" - see the next paragraph).  Stalemates are not
  1369. X    recognized per se, but when selecting its move the program assigns a
  1370. X    stalemate position a value of 0 so it will try for a stalemate if its
  1371. X    other options are worse.
  1372. X
  1373. X    The program takes one optional argument indicating the ply (lookahead)
  1374. X    it should use.  The default is 2, which is enough to keep it from
  1375. X    making flaming blunders.  The higher the ply, the better the play, and
  1376. X    the longer you have to wait.  For example, at a ply of 2, a response to
  1377. X    the PK4 opening takes about 1.8 CPU seconds on a SPARC ELC when
  1378. X    compiled -O with Sun cc.  A ply of 3 takes 13 CPU seconds (and results
  1379. X    in a different response to PK4) and a ply of 4 takes a little under 4
  1380. X    CPU minutes (and for PK4 comes up with the same response as a ply of
  1381. X    3).  A ply of 3 is in general good enough to avoid not only flaming
  1382. X    blunders but also immediately stupid moves altogether.  A ply of 4
  1383. X    will find all mate-in-two's.
  1384. X
  1385. X
  1386. X
  1387. X    This program is obfuscated in a number of ways.  First, it abuses the
  1388. X    contest rule regarding ';', '{', and '}' in the source not counting
  1389. X    against the non-whitespace character limit if followed by whitespace.
  1390. X    As can be seen from the build file, certain combinations of these
  1391. X    characters followed by a particular whitespace character are expanded
  1392. X    at build time into much-needed text.  Without this hack the program
  1393. X    wouldn't pass the character limit.  A nice side effect is that the
  1394. X    initial source is gloriously difficult to peruse.
  1395. X
  1396. X    Second, the rather ho-hum step has been taking of naming each variable
  1397. X    with a one or two letter identifier to render it meaningless (and save
  1398. X    space).  This tactic is rather effective in a complex program.
  1399. X
  1400. X    Third, the board is represented not as an array of pieces but rather as
  1401. X    an array of function pointers (with a separate array representing
  1402. X    whether a piece is white or black).  This obfuscates the program's
  1403. X    central data structure.  There is one function per type of piece; when
  1404. X    called they return 1 if the current move is illegal for that piece and
  1405. X    0 if it is legal.  The functions also as a side effect set a global
  1406. X    indicating the type of the piece (though the type can also be determined
  1407. X    by comparing the function pointer with the function itself).
  1408. X
  1409. X    Fourth, there are no independent routines for generating potential
  1410. X    moves.  Instead, the program generates its moves by brute force: for
  1411. X    every piece it controls on the board, it attempts to move it to every
  1412. X    square on the board.  Those moves that are legal it then explores to
  1413. X    see their effects (using alpha-beta search).  This tactic somewhat
  1414. X    obfuscates the algorithm used by the program.
  1415. X
  1416. X    Finally, there are three key constants that occur throughout the
  1417. X    program:  64, 8, and 3 (lg 8).  Rather than making these available at
  1418. X    compile-time, which provides a hint as to what the program is up to,
  1419. X    they are computed probabilistically at run-time.  An instance of the
  1420. X    "Inspection Paradox" is used which happens to produce a value that on
  1421. X    average is close to .64.  10000 instances of this value are computed,
  1422. X    added up, and then divided by 100.  Sometimes the value produced will
  1423. X    be 63 or 65 instead of 64 (but I've never observed any other values),
  1424. X    so the result is then rounded to the nearest multiple of 4, and then
  1425. X    the other constants are derived from it.
  1426. END_OF_FILE
  1427.   if test 6513 -ne `wc -c <'1992/vern.hint'`; then
  1428.     echo shar: \"'1992/vern.hint'\" unpacked with wrong size!
  1429.   fi
  1430.   # end of '1992/vern.hint'
  1431. fi
  1432. if test -f '1992/vern.orig.c' -a "${1}" != "-c" ; then 
  1433.   echo shar: Will not clobber existing file \"'1992/vern.orig.c'\"
  1434. else
  1435.   echo shar: Extracting \"'1992/vern.orig.c'\" \(3201 characters\)
  1436.   sed "s/^X//" >'1992/vern.orig.c' <<'END_OF_FILE'
  1437. X#include <stdio.h>
  1438. X;    m(x)(x<0?-1:!!x)
  1439. X;    g tj()-J
  1440. X;    a(x)(x<0?-x:x)
  1441. X;    h(x)((x)<=K?x:N-(x))
  1442. X;    f 9999
  1443. X;    A return
  1444. X;    H printf{ 
  1445. X;    R double
  1446. X;    U int
  1447. X;    V for
  1448. X;    b else
  1449. X;    u while
  1450. X;    B if
  1451. XU v,w,Y}     -1,W,J,p,F,o}    f,M,N,K,X,YY,_,P[f],s{ } ;
  1452. Xtypedef U{ *L} { } ;
  1453. XL q[f];
  1454. Xtj{ } {
  1455. XU S}    m{ v} +{ m{ w} <<K} ; 
  1456. XB{ !S} A J; 
  1457. XV{ v}    W+S; v!}    J&&!q[v]; v+}    S} ;
  1458. XA v; 
  1459. X}
  1460. Xk{ } {
  1461. X_}    K; 
  1462. XA v?a{ v} >1||w-Y||!q[J]:{ w-Y&&{ w-Y*2||q[W+Y*{ N+1} ]||
  1463. X    { J>>K} -K+{ Y-1} / 2} } ||q[J]; 
  1464. X}
  1465. Xz{ } {
  1466. X_}    5; 
  1467. XA v*w||g; 
  1468. X}
  1469. Xe{ } {
  1470. X_}     -2; 
  1471. XA{ v*v*v-v||w*w*w-w} &&{ J-W-2||{ W&N} -4||{ W>>K!}    { Y-1?N:0} } ||
  1472. X    q[W+1]||q[W+2]||q[W+K]!}    z||P[W+K]*Y<0} ; 
  1473. X}
  1474. XR VR{ } {
  1475. Xint PZ}    0x7fff; 
  1476. XA{ R} { rand{ } &PZ} /{ R} PZ; 
  1477. X}
  1478. Xl{ } {
  1479. X_}    K+1; 
  1480. XA{ v*w&&a{ v} -a{ w} } ||g; 
  1481. X}
  1482. XR UC{ } {
  1483. XR {    }    0,d; 
  1484. Xu{ { {    +}    d}    VR{ } } <1.0} ; 
  1485. XA d; 
  1486. X}
  1487. Xc{ } {
  1488. X_}     -11; 
  1489. XA a{ v} -a{ w} ||g; 
  1490. X}
  1491. XI{ ur,n,x} {
  1492. XW}    ur; 
  1493. XJ}    n; 
  1494. XB{ P[W]!}    Y||P[J]}    }    Y} A J+1;
  1495. Xv}    { J&N} -{ W&N} ; 
  1496. Xw}    { J>>K} -{ W>>K} ; 
  1497. XA q[W]{ } ||{ x&&QL{ W,J,s} } ; 
  1498. X}
  1499. XTT{ W} {
  1500. Xv}    w}    0; 
  1501. XA q[W]{ } +K; 
  1502. X}
  1503. Xs{ } {
  1504. XU j}     -1,{    ; 
  1505. XY}     -Y; 
  1506. XV{ {    }    0; {    <M; ++{    } {
  1507. XB{ j<0&&P[{    ]}    }     -Y&&TT{ {    } &&_}    }     -2} 
  1508. X{
  1509. Xj}    {    ; 
  1510. X{    }     -1; 
  1511. X}
  1512. Xb B{ j>}    0&&!I{ {    ,j,0} } A Y}     -Y; 
  1513. X}
  1514. XA!{ Y}     -Y} ; 
  1515. X}
  1516. Xbb{ } {
  1517. X_}    1; 
  1518. XA a{ v*w} -2; 
  1519. X}
  1520. Xuv{ } {
  1521. XV{ v}    0; v<f; ++v} {
  1522. XB{ h{ v>>K} }    }    0} {
  1523. XU S}    h{ v&N} ;
  1524. Xq[v]}    !S?z:{ S}    }    1?bb:{ S}    }    2?c:{ v&N>K?l:e} } } ; 
  1525. X}
  1526. Xb B{ h{ v>>K} }    }    1} q[v]}    k; 
  1527. Xb q[v]}    0;
  1528. XP[v]}    !!q[v]*{ 28-v} ; 
  1529. X}
  1530. X}
  1531. Xy{ } {
  1532. XU G}    Y,{    ; 
  1533. XJ}    0; 
  1534. XV{ {    }    0; {    <M; ++{    } {
  1535. X{    %8||H"\n%4o ",{    } ;
  1536. XB{ { Y}    P[{    ]}    m{ P[{    ]} } &&TT{ {    } } H"%c ",_+93+Y*16} ; 
  1537. Xb H"- "} ; 
  1538. X}
  1539. XH"\n    "} ; 
  1540. Xdo 
  1541. XH"%2d",{    ++&N} ; 
  1542. Xu{ {    &N} ; 
  1543. XY}    G; 
  1544. XH"\n"} ; 
  1545. X}
  1546. XO{ W,J} {
  1547. XB{ { q[J]}    q[W]} }    }    k&&h{ J>>K} }    }    0} q[J]}    l; 
  1548. XB{ q[W]}    }    e} B{ J-W}    }    2} O{ J+1,J-1} ;
  1549. Xb B{ W-J}    }    2} O{ W-1,W+1} ; 
  1550. XP[J]}    P[W]; 
  1551. Xq[W]}    0;
  1552. XP[W]}    0; 
  1553. X}
  1554. XQL{ W,J,D} L D; 
  1555. X{
  1556. XU HQ}    P[J],YX; 
  1557. XL AJ}    q[J],XY}    q[W]; 
  1558. XO{ W,J} ; 
  1559. XYX}    D{ } ;
  1560. XO{ J,W} ; 
  1561. Xq[J]}    AJ; 
  1562. Xq[W]}    XY; 
  1563. XP[J]}    HQ; 
  1564. XA YX; 
  1565. X}
  1566. XC{ } {
  1567. XU {    ,j,BZ}    0; 
  1568. XV{ {    }    0; {    <M; ++{    } {
  1569. XL Z}    q[{    ]; 
  1570. XB{ Z} {
  1571. XU r}    h{ {    >>K} +h{ {    &N} ,G}    Y,
  1572. X    S}    Z}    }    z?88:{ Z}    }    k?11+r+{ P[{    ]<0?N-{ {    >>K} :{ {    >>K} } :
  1573. X{ Z}    }    l?124-{ { YY<8&&{ { {    &N} !}    K||
  1574. X    { {    >>K} !}    { P[{    ]>0?0:N} } } ?M:0} :
  1575. X{ Z}    }    c?41+r:{ Z}    }    e?f-r-r:36+r+r} } } } ; 
  1576. XY}    P[{    ];
  1577. XV{ j}    0; j<M; ++j} B{ !I{ {    ,j,0} } S+}    { P[j]?5:1} ; 
  1578. XBZ+}    G}    }    Y?S:-S;
  1579. XY}    G; 
  1580. X}
  1581. X}
  1582. XB{ !{ ++X&M-1} } write{ 1,".",1} ; 
  1583. XA BZ; 
  1584. X}
  1585. XPX{ } {
  1586. XU {    ,Q}    0,XP}    0,JZ}    M*M,E}     -f,t,S}    o; 
  1587. XB{ !F--} A++F+C{ } ;
  1588. XV{ {    }    0; {    <JZ; ++{    } B{ !I{ {    >>K+K,{    &M-1,1} } {
  1589. XY}     -Y; 
  1590. Xo}     -E;
  1591. Xt}     -QL{ {    >>K+K,{    &M-1,PX} ; 
  1592. XY}     -Y; 
  1593. XB{ t>E} {
  1594. X++XP; 
  1595. XQ}    {    ; 
  1596. XE}    t; 
  1597. XB{ E>}    S} 
  1598. XA++F,E; 
  1599. X}
  1600. X}
  1601. XB{ !XP} E}    s{ } ?-f+1:0; 
  1602. Xp}    Q; 
  1603. XA++F,E; 
  1604. X}
  1605. XRZ{ } {
  1606. XU {    ,j,T}    0; 
  1607. XV{ ; ; } {
  1608. Xy{ } ; 
  1609. Xo}    f; 
  1610. Xdo{
  1611. XH"\n%d %d %d %s ",X,T,C{ } ,s{ } ?"!":">"} ;
  1612. Xfflush{ stdout} ; 
  1613. X}
  1614. Xu{ scanf{ "%o%o",&{    ,&j} !}    2||I{ {    ,j,1} } ;
  1615. XO{ {    ,j} ; 
  1616. Xy{ } ; 
  1617. XX}    0; 
  1618. X++YY;
  1619. XY}     -Y; 
  1620. XT}    PX{ } ; 
  1621. X{    }    p>>{ K<<1} ; 
  1622. Xj}    p&{ M-1} ; 
  1623. XB{ I{ {    ,j,1} } {
  1624. XH"Rats!\n"} ; 
  1625. XA; 
  1626. X}
  1627. XO{ {    ,j} ; 
  1628. XY}     -Y; 
  1629. XB{ T>M*M} H"\nHar har.\n"} ; 
  1630. X}
  1631. X}
  1632. Xmain{ ac,av} char**av; 
  1633. X{
  1634. Xlong time{ } ,j}    time{ &j} ; 
  1635. XR {    }    0; 
  1636. Xsrand{ { U} j} ;
  1637. XV{ M}    0; M<}    f; ++M} {    +}    UC{ } ; 
  1638. XM}    {    /100;
  1639. XB{ M&3} ++M; 
  1640. XB{ M&1} --M; 
  1641. XV{ N}    1; N*N<M; ++N} ;
  1642. XK}     --N/2; 
  1643. XF}    ac>1?atoi{ av[1]} :2; 
  1644. Xuv{ } ;
  1645. XRZ{ } ; 
  1646. X}
  1647. END_OF_FILE
  1648.   if test 3201 -ne `wc -c <'1992/vern.orig.c'`; then
  1649.     echo shar: \"'1992/vern.orig.c'\" unpacked with wrong size!
  1650.   fi
  1651.   # end of '1992/vern.orig.c'
  1652. fi
  1653. if test -f '1992/westley.hint' -a "${1}" != "-c" ; then 
  1654.   echo shar: Will not clobber existing file \"'1992/westley.hint'\"
  1655. else
  1656.   echo shar: Extracting \"'1992/westley.hint'\" \(4374 characters\)
  1657.   sed "s/^X//" >'1992/westley.hint' <<'END_OF_FILE'
  1658. XBest Small Program: <merlyn@digibd.com> Brian Westley (aka Merlyn LeRoy)
  1659. X
  1660. X    Brian Westley (aka Merlyn LeRoy)
  1661. X    Digi International
  1662. X    1026 Blair Ave.
  1663. X    St. Paul, MN  55104
  1664. X    USA
  1665. X
  1666. X
  1667. XJudges' comments:
  1668. X
  1669. X    If lost:
  1670. X    make whereami
  1671. X    
  1672. X    Then run:
  1673. X    whereami lat long
  1674. X    
  1675. X    Where lat and long correspond to your latitude and longitude.
  1676. X
  1677. X    To find the approximate place where this entry was judged, type:
  1678. X
  1679. X    whereami 37 -122    (- means west of meridian)
  1680. X    
  1681. X
  1682. XSelected notes from the author:
  1683. X
  1684. X    Run the program with your latitude & longitude as integer
  1685. X    arguments; it will produce a map made up of '!' with the given
  1686. X    position marked with either a '"' (if the position is over a '!')
  1687. X    or a '#' (if the position is over a space).  Southern latitudes
  1688. X    and western longitudes are entered as negative numbers.  For
  1689. X    example, to find San Francisco, run with "prog 38 -122".  The
  1690. X    resolution of the map is five degrees horizontally, ten degrees
  1691. X    vertically.  The map is a Mercator projection with equal spacing
  1692. X    of the latitudes, so the areas near the poles are very distorted.
  1693. X    Latitudes near the poles and Antarctica are not shown.
  1694. X
  1695. X    The program requires the ASCII character set, putchar(), atoi(),
  1696. X    and a display that auto-wraps at 80 characters(!).  If your display
  1697. X    does not work this way, you will have to massage the output;
  1698. X    for example, you can pipe it to a file and edit it with vi,
  1699. X    which will do autowrap for you.
  1700. X
  1701. X    Lint complains that main() returns a random value and I'm not
  1702. X    checking the value that putchar() returns.  Scandalous!
  1703. X
  1704. X    If you run it with fewer than 2 arguments, it will likely
  1705. X    give you an exception, as it will access arguments that
  1706. X    don't exist and characters before a string constant.
  1707. X
  1708. X    How it works:
  1709. X
  1710. X    The map is printed as one long string of ' ' and '!' characters,
  1711. X    with the autowrap used to stack up slices of 80.  The map data is
  1712. X    a string; the first character is how many '!'s are printed
  1713. X    ('A'=1, 'B'=2, etc), the second character is how many ' 's, the
  1714. X    third is how many '!'s, etc.  ASCII characters less than 'A'
  1715. X    print no characters but still change the polarity, so any map
  1716. X    of ' 's and '!'s is possible.  This is done in the putchar()
  1717. X    argument as "33^l&1", where l is the character position+4; if
  1718. X    l is odd, ' ' is printed, if l is even, '!' is printed.
  1719. X
  1720. X    The position of latitude & longitude is changed into a single
  1721. X    character position within the one long string via the first
  1722. X    expression "d = latitude/10*80 - longitude/5 - offset"  The
  1723. X    latitude is divided by ten because the vertical resolution is
  1724. X    ten degrees, then multiplied by 80 because of the 80 character
  1725. X    wrap (i.e. each ten degrees moves the position up or down one
  1726. X    entire row).  The longitude is divided by five and added, because
  1727. X    five degrees of change moves the location one character.  The signs
  1728. X    are opposite because latitude is decreasing and longitude is
  1729. X    increasing as you go from upper left to lower right.  The offset
  1730. X    is where the origin (latitude=0, longitude=0) is found.
  1731. X
  1732. X    The position counting down to zero changes the putchar() from
  1733. X    printing ('!' or ' ') to printing ('"' or '#').
  1734. X
  1735. X    The "H E L L O,   W O R L D!" string inside the data string
  1736. X    prints the line of blanks past Tierra del Fuego and the last
  1737. X    blank line.  It's just for show, really.
  1738. X
  1739. X    Since the resolution is coarse, a few costal cities are shown to
  1740. X    be just off the map; this is an unavoidable artifact.  The map
  1741. X    is reasonably accurate.
  1742. X
  1743. X    Here are some cities you might like to try:
  1744. X
  1745. X         New York  41  -74       Los Angeles  34 -118
  1746. X           London  52    0             Paris  45    2
  1747. X           Moscow  56   38           Beijing  40  116
  1748. X        New Delhi  29   77    Rio de Janeiro -23  -43
  1749. X           Sydney -34  151             Tokyo  36  140
  1750. X
  1751. XFor a domestic (USA) version with higher resolution, try:
  1752. X---cut---
  1753. Xmain(l,a,n,d)char**a;{for(d=atoi(a[1])/2*80-atoi(a[2])-2043;
  1754. Xn="bnaBCOCXdBBHGYdAP[A M E R I C A].AqandkmavX|ELC}BOCd"
  1755. X[l++-3];)for(;n-->64;)putchar(!d+++33^l&1);}
  1756. X---cut---
  1757. XThe code will test the 80-column wrap and document itself if it is
  1758. Xjoined together as one 160-character line and listed.  You should see:
  1759. X
  1760. Xmain(l,a,n,d)...
  1761. X[A M E R I C A]...
  1762. X
  1763. X...going down the left edge if your terminal autowraps at 80 characters.
  1764. END_OF_FILE
  1765.   if test 4374 -ne `wc -c <'1992/westley.hint'`; then
  1766.     echo shar: \"'1992/westley.hint'\" unpacked with wrong size!
  1767.   fi
  1768.   # end of '1992/westley.hint'
  1769. fi
  1770. echo shar: End of archive 3 \(of 5\).
  1771. cp /dev/null ark3isdone
  1772. MISSING=""
  1773. for I in 1 2 3 4 5 ; do
  1774.     if test ! -f ark${I}isdone ; then
  1775.     MISSING="${MISSING} ${I}"
  1776.     fi
  1777. done
  1778. if test "${MISSING}" = "" ; then
  1779.     echo You have unpacked all 5 archives.
  1780.     rm -f ark[1-9]isdone
  1781. else
  1782.     echo You still must unpack the following archives:
  1783.     echo "        " ${MISSING}
  1784. fi
  1785. exit 0
  1786. exit 0 # Just in case...
  1787.