diff --git a/2001/westley/.gitignore b/2001/westley/.gitignore index 50cb97837..41c62376a 100644 --- a/2001/westley/.gitignore +++ b/2001/westley/.gitignore @@ -2,5 +2,5 @@ westley westley.alt westley2 westley2.c -westley3 -westley3.c +westley.punch +westley.sort diff --git a/2001/westley/Makefile b/2001/westley/Makefile index 04e7662ee..05a426a77 100644 --- a/2001/westley/Makefile +++ b/2001/westley/Makefile @@ -63,7 +63,7 @@ CDEFINE= # Include files that are needed to compile # -CINCLUDE= +CINCLUDE= -include stdio.h # Optimization # @@ -113,7 +113,7 @@ PROG= ${ENTRY} # OBJ= ${PROG}.o DATA= -TARGET= ${PROG} +TARGET= ${PROG} ${PROG}.sort ${PROG}.punch # ALT_OBJ= ${PROG}.alt.o ALT_TARGET= ${PROG}.alt @@ -143,6 +143,10 @@ westley2: westley2.c westley3: westley3.c ${CC} ${CFLAGS} $< -o $@ ${LIBS} +${PROG}.sort: ${PROG}.sort.c + ${CC} ${CFLAGS} $< -o $@ ${LIBS} + + # alternative executable # alt: data ${ALT_TARGET} diff --git a/2001/westley/README.md b/2001/westley/README.md index cf03a2d54..140a5a51b 100644 --- a/2001/westley/README.md +++ b/2001/westley/README.md @@ -1,12 +1,8 @@ # Best position-independent code - Brian Westley - Firesign Theatre webmaster - 1906 James Ave - St. Paul, MN 55105 - US - - http://www.westley.org +Brian Westley +US + ## To build: @@ -22,20 +18,20 @@ make ## Try: +[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) added the script +[westley.sh](westley.sh) to automate a heap of commands that we, the IOCCC +judges, suggested, as well as some additional ones that he thought would be fun. +These include the below sort and punch card versions that he added, described +below, based on the author's remarks. Thank you Cody! + ```sh -./westley < westley.c > westley2.c -make westley2 -echo 'Bozos, please deflate shoes before entering the bus!'| ./westley2 -sort -b < westley2.c > westley3.c -make westley3 -./westley3 < westley.c | diff - westley.c -./westley3 < westley.c | diff - westley2.c -./westley3 < westley.c | diff - westley3.c +./westley.sh ``` -### Alternate code +### Alternate code: -An alternate version of this entry, `westley.alt.c`, is provided. This alternate code may be less portable. +An alternate version of this entry, [westley.alt.c](westley.alt.c), is provided. +This alternate code might be less portable. To compile this alternate version: @@ -45,7 +41,27 @@ make alt Use `westley.alt` as you would `westley` above. -## Judges' remarks +### Sorted code: + +The author stated that one can sort (with ignoring leading blanks i.e. `sort +-b`) the code by line and it will always sort the order of the input. + +Use `westley.sort` as you would `westley` above. + +### Punch card code: + +The author also stated that if you just sort the code you'll get the with +`sort`) version that just prints out the punch card. Cody put this in +[westley.punch.c](westley.punch.c) specifically so that Westley can punch +everyone in the face! :-) This is also compiled by default. + +To use, try: + +```sh +echo 'Brian Westley does it again!' | ./westley.punch 2>/dev/null +``` + +## Judges' remarks: Try copying the source to a new file and changing around the order of the lines. Does it produce the exact same output? @@ -53,16 +69,19 @@ order of the lines. Does it produce the exact same output? By changing the order of the source, figure out in how many different ways this program can transform input to output. -This assortment obfuscated lines takes position-independant code +This assortment obfuscated lines takes position-independent code to a new level! :-) -## Author's remarks +We find it amazing that with just 28 lines of code (not counting comments and +blank lines) there are `28!` or ``304,888,344,611,713,860,501,504,000,000`` +versions of the program, all valid C! -Punch cards, or Hollerith cards, were becoming obsolete just -as C was becoming more popular*; this is rather unfortunate, -because C has an advantage over many other languages when it -comes to punch cards - C programs can be written to be "drop -proof". +## Author's remarks: + +[Punch cards](https://en.wikipedia.org/wiki/Punched_card), or Hollerith cards, +were becoming obsolete just as C was becoming more popular\*; this is rather +unfortunate, because C has an advantage over many other languages when it comes +to punch cards - C programs can be written to be "drop proof". Consider the following C program: @@ -76,7 +95,7 @@ c(){printf("C");} This program will compile and run no matter what order the lines are in. If you punch it on cards (one line of code per card, naturally) and drop them, you don't need to put them in -any particular order**; it will always produce "ABC" as output. +any particular order\*\*; it will always produce `ABC` as output. You can also use global variables: @@ -96,9 +115,9 @@ test(a,b){return a;} main(){if (test(0,1)) printf("T"); else printf("F");} ``` -This program will print out "T" if the #define statement -falls between the declaration of test() and its use in -main(), otherwise it will print out "F". Furthermore, +This program will print out `T` if the `#define` statement +falls between the declaration of `test()` and its use in +`main()`, otherwise it will print out `F`. Furthermore, you can use the same call to test() repeatedly in different lines to return different values: @@ -120,16 +139,20 @@ number generator... Of course, there are drawbacks to C programming on punch cards; an 80-character line limit can be restricting, and (to be maximally portable) you need to use trigraphs for -the characters "^[]{}\" (these aren't found on every +the characters `^[]{}\` (these aren't found on every keypunch, and have various encodings). My C program entry does the following: -1) reads in lines -2) rearranges the lines, or not -2a) if it rearranges the lines, they are sorted or scrambled -3) reverses the order of the lines, or not -4) prints out the lines as either text or EBCDIC punch cards. +1. Reads in lines. + +2. Rearranges the lines, or not. + - if it rearranges the lines, they are sorted or scrambled. + +3. Reverses the order of the lines, or not. + +4. Prints out the lines as either text or +[EBCDIC](https://en.wikipedia.org/wiki/EBCDIC) punch cards. The code, as written, scrambles the input and prints it out as normal text, so you can simulate 'dropping' the cards. @@ -137,19 +160,19 @@ You can repeatedly scramble the code to get all 12 variants (but the scrambling isn't very random; it's just a bubble sort with a random number, so some variants are more common than others). You can also just swap the arguments in the -calls to t() in all combinations to get all the variations. +calls to `t()` in all combinations to get all the variations. If you sort the lines, you will get the version that just prints out the input as punch cards (you will need to display at least 82 columns of text, or clip the last few chars by -piping it through "sed s/...$//"). If you use this on the -original code, you will see that it spells out "HOLLERITH" +piping it through `sed s/...$//`). If you use this on the +original code, you will see that it spells out `HOLLERITH` when punched on cards (you can see the tall, thin letters -spelling out "HOLLERITH" if you turn the C code sideways). -You will also see why "/KC 0000 K" is a "Hollerith emoticon". +spelling out `HOLLERITH` if you turn the C code sideways). +You will also see why `/KC 0000 K` is a `Hollerith emoticon`. Unrecognized characters are punched as a lace column. (You can see an ASCII simulation of the code as punch cards -by looking at card.gif) +by looking at `card.gif`.) For a nice test pattern, try @@ -158,29 +181,30 @@ For a nice test pattern, try ``` If you want to analyze the program, sorting the lines while -ignoring leading blanks works best (sort -b). This will +ignoring leading blanks works best (`sort -b`). This will produce the version that just reverses the line order, and the routines in the code are in a sensible order. This program should work on EBCDIC computers. It assumes -that the time_t ptr param to time() will work with an int -ptr, and that "passing through" a char[][] array as a simple -char* is ok. Your compiler MUST understand trigraphs, or it +that the `time_t` ptr param to `time()` will work with an `int` +ptr, and that "passing through" a `char[][]` array as a simple +`char *` is OK. Your compiler MUST understand trigraphs, or it will miss the trigraph backslash before the double quote in -the K string and complain about a malformed string; for GNU -C, use -ansi or -trigraphs. Entering a line of more than 80 +the `K` string and complain about a malformed string; for GNU +C, use `-ansi` or `-trigraphs`. Entering a line of more than 80 characters, or more than 81 lines, will jam the card reader. -I've used the a[b] ==> *(a+b) trick, because this is -actually shorter than the trigraph version of a??(b??). +I've used the `a[b]` ==> `*(a+b)` trick, because this is +actually shorter than the trigraph version of `a??(b??)`. With 28 lines of code (not counting the blank lines or the -comment), there are technically 28! different programs, or -304,888,344,611,713,860,501,504,000,000 different versions, +comment), there are technically `28!` different programs, or +`304,888,344,611,713,860,501,504,000,000` different versions, all legal C. -*except in Florida voting machines -**all cards must be face down, nine-edge first, of course. +\* except in Florida voting machines + +\*\* all cards must be face down, nine-edge first, of course. ## Copyright and CC BY-SA 4.0 License: diff --git a/2001/westley/westley.punch.c b/2001/westley/westley.punch.c new file mode 100644 index 000000000..41738daa3 --- /dev/null +++ b/2001/westley/westley.punch.c @@ -0,0 +1,37 @@ + + + + + + + + + T(c,r) ??< return Y(c, r)?'??(' :' '; ??> + W(r,a,b,c)?? + /* { /KC 0000 K } */ + char*B=" yz0123456789"; + U(c,i)char*c; ?? + char* B,*r; X(c,k)?? + L(c,i,j)char c??(81??)??(81??);?? + char*r= "008y8yy8yyyyz8z8z88888z0yyz888 8888 88y00zz00z0088"; + E(r,s)char*r,*s; ??< if(t( 0,1)&& F(r,s)<0)G(r,s); ??> + char*d= "yyzzyzz zz z0y000 zz 00yzz00y00yzz Brian Westley zyy00yy0yy 0" ; ; ; + t(a,b)?? +#define t(a,b) t(b,a) +A(i ,c,j ,k) char *c; ??< for(j= -1; ++j +D(c,i,j) char c??(81??)??(81??);?? +F(r,s)char*r,*s; ?? +G(r,s)char*r,*s; ?? +H()?? return rand()-rand(); ??> +J(i,c,j)char*c; ?? +M(i,c)char c??(81??)??(81??);?? +P(c)char*c; ?? +Q(t,i)??< printf(t?" ":"|"); for(; i<80; i++) printf("_"); puts(t?"_":"|"); ??> +R(c,r) char *c; ??< printf( "/%-80s|??/n" ,c); for (; r< 13; r++)S (c,r,0); ??> +S(c,r,i)char*c; ?? +V(c,k,i) char*k; ?? +char* K;Y (c ,r) ??< int i=V ( tolower (c) ,K); return(i <0)?1 :Z(c ,r, i); ??> +char* d,*m,*B; Z(c,i,k)?? +char*K= "gh$j|lm'pq&rvz#);@_winky,.%/+*!=3-284106579 (:obfuscated??/?" ; ; +char*m= "7831734578 9547693564569528334164263z284106579 52626423135477"; ; ; ; +main(i)?? diff --git a/2001/westley/westley.sh b/2001/westley/westley.sh new file mode 100755 index 000000000..2e92accca --- /dev/null +++ b/2001/westley/westley.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +echo "./westley < westley.c 2>/dev/null > westley2.c" +./westley < westley.c 2>/dev/null > westley2.c +make westley2 2>/dev/null 1>&2 +echo +echo "echo 'Bozos, please deflate shoes before entering the bus!'| ./westley2 2>/dev/null" +echo 'Bozos, please deflate shoes before entering the bus!'| ./westley2 2>/dev/null +echo + +make westley.sort 2>/dev/null 1>&2 +echo +echo "./westley.sort < westley.c 2>/dev/null | diff - westley.c" +# SC2094 (info): Make sure not to read and write the same file in the same pipeline. +# shellcheck disable=SC2094 +./westley.sort < westley.c 2>/dev/null | diff - westley.c +echo "./westley.sort < westley.c 2>/dev/null | diff - westley2.c" +./westley.sort < westley.c 2>/dev/null | diff - westley2.c +echo "./westley.sort < westley.c 2>/dev/null | diff - westley.sorted.c" +./westley.sort < westley.c 2>/dev/null | diff - westley.sorted.c +echo "./westley.sort < westley.c 2>/dev/null | diff - westley.punch.c" +./westley.sort < westley.c 2>/dev/null | diff - westley.punch.c + +echo +# SC2028 (info): echo may not expand escape sequences. Use printf. +# shellcheck disable=SC2028 +echo "printf \"1\n\4\n5\" | ./westley 2>/dev/null" +printf "1\n4\n5" | ./westley 2>/dev/null + +echo +# SC2028 (info): echo may not expand escape sequences. Use printf. +# shellcheck disable=SC2028 +echo "printf \"1\n\4\n5\" | ./westley 2>/dev/null" +printf "1\n4\n5" | ./westley 2>/dev/null + +echo +echo "echo 'Hello, world!' | ./westley.punch 2>/dev/null" +echo 'Hello, world!' | ./westley.punch 2>/dev/null diff --git a/2001/westley/westley.sort.c b/2001/westley/westley.sort.c new file mode 100644 index 000000000..99591b5bb --- /dev/null +++ b/2001/westley/westley.sort.c @@ -0,0 +1,37 @@ + + + + + + + + +#define t(a,b) t(b,a) + /* { /KC 0000 K } */ +A(i ,c,j ,k) char *c; ??< for(j= -1; ++j +D(c,i,j) char c??(81??)??(81??);?? + E(r,s)char*r,*s; ??< if(t( 0,1)&& F(r,s)<0)G(r,s); ??> +F(r,s)char*r,*s; ?? +G(r,s)char*r,*s; ?? +H()?? return rand()-rand(); ??> +J(i,c,j)char*c; ?? + L(c,i,j)char c??(81??)??(81??);?? +M(i,c)char c??(81??)??(81??);?? +P(c)char*c; ?? +Q(t,i)??< printf(t?" ":"|"); for(; i<80; i++) printf("_"); puts(t?"_":"|"); ??> +R(c,r) char *c; ??< printf( "/%-80s|??/n" ,c); for (; r< 13; r++)S (c,r,0); ??> +S(c,r,i)char*c; ?? + T(c,r) ??< return Y(c, r)?'??(' :' '; ??> + U(c,i)char*c; ?? +V(c,k,i) char*k; ?? + W(r,a,b,c)?? + char* B,*r; X(c,k)?? +char* K;Y (c ,r) ??< int i=V ( tolower (c) ,K); return(i <0)?1 :Z(c ,r, i); ??> +char* d,*m,*B; Z(c,i,k)?? + char*B=" yz0123456789"; +char*K= "gh$j|lm'pq&rvz#);@_winky,.%/+*!=3-284106579 (:obfuscated??/?" ; ; + char*d= "yyzzyzz zz z0y000 zz 00yzz00y00yzz Brian Westley zyy00yy0yy 0" ; ; ; +char*m= "7831734578 9547693564569528334164263z284106579 52626423135477"; ; ; ; + char*r= "008y8yy8yyyyz8z8z88888z0yyz888 8888 88y00zz00z0088"; +main(i)?? + t(a,b)?? diff --git a/bugs.md b/bugs.md index d72c79c40..c9501ffdf 100644 --- a/bugs.md +++ b/bugs.md @@ -1449,6 +1449,22 @@ The author said that they compiled it with [gcc version a certain gcc version is necessary but it might be helpful to download and compile that version to test it. +## [2001/westley](2001/westley/westley.c) ([README.md](2001/westley/README.md)) +## STATUS: missing files - please provide them + +The author referred to the file `card.gif` but this appears to be missing. Do +you have it? If you do please provide it and thank you! + +## STATUS: uses gets() - change to fgets() if possible (in some cases getline() works) + +The code also uses `gets()` which, without redirecting stderr to `/dev/null`, +can show an obnoxious warning every time it's run. In the script +[2001/westley/westley.sh](2001/westley/westley.sh) that [Cody Boone +Ferguson](/winners.html#Cody_Boone_Ferguson) added stderr is in fact redirected +to `/dev/null` to prevent this warning but it would probably be better if it was +changed to use `fgets()` (which he might end up doing). + + # 2002 There was no IOCCC in 2002.