From ee4ee3497df5784b7daf4d8cda61461756269d37 Mon Sep 17 00:00:00 2001 From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com> Date: Fri, 14 Apr 2023 06:25:34 -0700 Subject: [PATCH] Update 1993 winning entries' README.md files Format and typo fixes. Starting with this year I actually did more thorough typo fixes. It might be that I did some of this in earlier years too but I am sure I did it for this year and beyond (at least up through 1995 .. not sure about years beyond that that I have also edited). Even so I'll probably want to do another pass through all files before I can say that the typo issue is resolved. That includes possibly other files and the worst of all files in my entries. --- 1993/dgibson/README.md | 4 +- 1993/ejb/README.md | 66 ++++++----- 1993/jonth/README.md | 22 ++-- 1993/leo/Makefile | 4 +- 1993/leo/README.md | 93 ++++++++------- 1993/lmfjyh/README.md | 124 ++++++++++---------- 1993/plummer/README.md | 38 +++--- 1993/schnitzi/README.md | 57 +++++---- 1993/vanb/README.md | 250 ++++++++++++++++++++++------------------ 9 files changed, 360 insertions(+), 298 deletions(-) diff --git a/1993/dgibson/README.md b/1993/dgibson/README.md index dfd8d41fa..2f9a58128 100644 --- a/1993/dgibson/README.md +++ b/1993/dgibson/README.md @@ -21,7 +21,7 @@ make all where: -`datafile` is the initial pattern (default: dgibson.data1) +`datafile` is the initial pattern (default: [dgibson.data1](dgibson.data1)) ## Try: @@ -59,7 +59,7 @@ a rectangular grid of cells can be alive or dead, and cells with more than 3 or less than 2 (out of 8) live neighbours die, and empty cells with exactly 3 neighbours give birth. -### Some notes: +### Some notes - the "STAT n" information does not have to be present in the initial configuration diff --git a/1993/ejb/README.md b/1993/ejb/README.md index e5a548aef..e916d9504 100644 --- a/1993/ejb/README.md +++ b/1993/ejb/README.md @@ -1,22 +1,28 @@ # Best Obfuscated Algorithm - E. Jay Berkenbilt - Engineering Research Associates - 1595 Springhill Road - Vienna, VA 22182-2235 - USA +E. Jay Berkenbilt +Engineering Research Associates +1595 Springhill Road +Vienna, VA 22182-2235 +USA ## To build: - make all +```sh +make all +``` ## To run: - ./ejb level +```sh +./ejb level +``` where: - level a value from -128 to 127 +```sh +level a value from -128 to 127 +``` ## Judges' remarks: @@ -33,20 +39,22 @@ We note that this also works under macOS just fine. ## Author's remarks -WHAT THIS PROGRAM DOES -====================== +### What this program does -### Output solution to Towers of Hanoi for five rings: +#### Output solution to Towers of Hanoi for five rings: - ./ejb 5 +```sh +./ejb 5 +``` The format of the output for the Towers of Hanoi case is simply a text description of how to solve the puzzle. -### Output solution to the Patience puzzle for six rings: +#### Output solution to the Patience puzzle for six rings: - - ./ejb -6 +```sh +./ejb -6 +``` For the patience puzzle, the output is a sequence binary codes representing @@ -55,8 +63,7 @@ A "1" means the ring is on the U; a "0" means it is off the U. The program prints the word "Invalid" in response to illegal command line parameters. -MOTIVATION -========== +### Motivation Most people who have written software for other people have been asked to count lines of code. Naturally, this brings up the @@ -66,25 +73,24 @@ always provide a meaningful measure of code size. This is especially true in this program where the number of semicolons itself is ambiguous. Does it have two or three? In addition, the only "C" keyword this program uses besides type names and -qualifiers is "return", and the only function defined in the code -is "main". The level of complexity of the program without multiple +qualifiers is `return`, and the only function defined in the code +is `main`. The level of complexity of the program without multiple semicolons, statements, and functions is achieved by abusing C -operators, especially the comma operator. Considerable use of ||, -&&, and ? : helps too. In addition, main is called recursively. -The null pointer that terminates argv is used to pass additional +operators, especially the comma operator. Considerable use of `||`, +`&&`, and `? :` helps too. In addition, main is called recursively. +The NULL pointer that terminates argv is used to pass additional information into main. Even though the algorithms used by this code are simple, this program is still hard to follow even when indented properly. (It is pretty hard to indent this code reasonably, however.) -Although this program is has only been tested on UNIX systems but -will probably run on just about any machine with an ANSI C -compiler. It does not use the C preprocessor at all. The only -functions it uses are atoi, malloc, memset, printf, and puts. It -does, however, require that the architecture it runs on have bytes -that are at least eight bits long and pointers that are at least -four bytes long. In addition, it requires an ANSI compiler since -it uses "signed char" and ANSI-style function declarations. +Although this program has only been tested on UNIX systems it will probably run +on just about any machine with an ANSI C compiler. It does not use the C +preprocessor at all. The only functions it uses are `atoi()`, `malloc()`, +`memset()`, `printf()`, and `puts()`. It does, however, require that the +architecture it runs on have bytes that are at least eight bits long and +pointers that are at least four bytes long. In addition, it requires an ANSI +compiler since it uses "signed char" and ANSI-style function declarations. ## Copyright and CC BY-SA 4.0 License: diff --git a/1993/jonth/README.md b/1993/jonth/README.md index e634f3250..f199b4855 100644 --- a/1993/jonth/README.md +++ b/1993/jonth/README.md @@ -1,14 +1,16 @@ # Most Obfuscated X Program -Jon Thingvold -University of Oslo -Sogn Studentby 8231 -N 0858 Oslo -Norway +Jon Thingvold +University of Oslo +Sogn Studentby 8231 +N 0858 Oslo +Norway ## To build: - make all +```sh +make all +``` NOTE: this entry requires `X11/Xlib.h` header file and the X11 library to compile. macOS users running Mountain Lion and later will need to download and @@ -33,11 +35,13 @@ prepended to them. Thank you Yusuke and Cody for your assistance! ## To run: - ./jonth # must be run on an X11 server +```sh +./jonth # must be run on an X11 server +``` ## Judges' remarks: -Use 'h' and 'l' to shift objects left or right. Use 'k' to +Use `h` and `l` to shift objects left or right. Use `k` to rotate and press SPACE to drop. This program's output may be even more obfuscated when played @@ -52,7 +56,7 @@ This program is also an example of data abstraction. The X array is after initialization hidden by the well defined macros `t`, `u` and `F`. This program is highly portable as it runs on a "Notebook" size SPARC. -This program will not work on machines with `sizeof(int)!=sizeof(void *)`. +This program will not work on machines where `sizeof(int)!=sizeof(void *)`. ## Copyright and CC BY-SA 4.0 License: diff --git a/1993/leo/Makefile b/1993/leo/Makefile index cac73d755..ea6f1a888 100644 --- a/1993/leo/Makefile +++ b/1993/leo/Makefile @@ -114,14 +114,14 @@ DATA= TARGET= ${PROG} # ALT_OBJ= -ALT_TARGET= +ALT_TARGET= mind ################# # build the entry ################# # -all: data ${TARGET} +all: data ${TARGET} ${ALT_TARGET} @${TRUE} .PHONY: all alt data everything clean clobber install \ diff --git a/1993/leo/README.md b/1993/leo/README.md index 263d770e7..1f5e333b2 100644 --- a/1993/leo/README.md +++ b/1993/leo/README.md @@ -1,14 +1,16 @@ # Best Game - Leonid A. Broukhis - Moscow Centre of SPARC Technology - 123481 Liberty St., - 89-1-95 Moscow - Russia +Leonid A. Broukhis +Moscow Centre of SPARC Technology +123481 Liberty St., +89-1-95 Moscow +Russia ## To build: - make all +```sh +make all +``` [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) fixed this to work with modern compilers. Thank you Cody! @@ -18,19 +20,23 @@ modern compilers. Thank you Cody! To have the computer guess: - ./leo [colors] +```sh +./leo [colors] +``` To guess the computer's number: - ./mind [colors] +```sh +./mind [colors] +``` where: - colors number of possible colors (1 to 15) (default: 6) +[colors] is the number of possible colors (1 to 15) (default: 6) ## Judges' remarks: -By default, the number of colors if 6. You may specify a +By default, the number of colors is 6. You may specify a value of between 1 and 15 colors. See the author's notes for instructions of how to play. @@ -39,8 +45,9 @@ International Internet community. ## Author's remarks: -This program plays mastermind, if you call it by a name ending by -'d', otherwise it _solves_ mastermind. Call it without parameters +This program plays +[Mastermind](https://en.wikipedia.org/wiki/Mastermind_(board_game), if you call it by a name ending by +'d', otherwise it _solves_ Mastermind. Call it without parameters to use 6 digits (colors), or indicate the number of possible digits (you cannot change the number of positions so easily). @@ -48,14 +55,14 @@ The number in parentheses is the number of possible combinations, based on previous questions and answers. If you solve the puzzle, "(1)" indicates that your previous moves are enough to give correct answer. If the program acts as solver and terminates prematurely, -it means that you have mistaken in your answers to its guesses. +it means that you're mistaken in your answers to its question(s). Question marks indicate the number of digits you have to enter (either 4 when you guess or 2 when computer guesses). Note that the program uses the same code for both player and -solver, and the only place where it makes difference is the +solver, and the only place where it makes a difference is the interactive part. Many obfuscations have been made to achieve -this. An expression giving (bulls * 16 + cows) from two numbers +this. An expression giving `(bulls * 16 + cows)` from two numbers is, however, quite straightforward :-) , as well as the arithmetic of binary coded colors-base numbers is. @@ -66,35 +73,39 @@ backspaces. Do "disable scrolling" on cmdtool or similar emulators. #### Bugs: Please don't type ^D at the prompt!! -##### EXAMPLE: Suppose we think of 1234: +##### EXAMPLE: Suppose we think of 1234 - judges-385> leo - (1296): 6433 - ?? 12 # one 3 is a bull, another is a cow, and 4 is a cow - (160): 5363 - ?? 02 # both 3's are cows - (21): 4231 - ?? 22 # 2 and 3 are bulls, 4 and 1 are cows - (2): 4132 - ?? 13 # 3 is a bull; 1, 2 and 4 are cows - (1): 1234 - ?? 40 # you may enter everything there +``` +judges-385> ./leo + (1296): 6433 + ?? 12 # one 3 is a bull, another is a cow, and 4 is a cow + (160): 5363 + ?? 02 # both 3's are cows + (21): 4231 + ?? 22 # 2 and 3 are bulls, 4 and 1 are cows + (2): 4132 + ?? 13 # 3 is a bull; 1, 2 and 4 are cows + (1): 1234 + ?? 40 # you may enter everything there +``` -##### EXAMPLE: Guess the computer's number: +##### EXAMPLE: Guess the computer's number - judges-387> mind - (1296): ???? 1122 # my strategy isn't the best, just as example - 00 - (256): ???? 3344 - 20 - (18): ???? 5566 - 02 - (6): ???? 3654 - 11 - (2): ???? 3355 - 00 - (1): ???? 6444 - 40 # we have guessed the number +``` +judges-387> ./mind +(1296): ???? 1122 # my strategy isn't the best, just as example +00 +(256): ???? 3344 +20 +(18): ???? 5566 +02 +(6): ???? 3654 +11 +(2): ???? 3355 +00 +(1): ???? 6444 +40 # we have guessed the number +``` ## Copyright and CC BY-SA 4.0 License: diff --git a/1993/lmfjyh/README.md b/1993/lmfjyh/README.md index 7838d3f4d..6f1052740 100644 --- a/1993/lmfjyh/README.md +++ b/1993/lmfjyh/README.md @@ -1,9 +1,9 @@ # Most Versatile Source - Jyrki Holopainen - Oy LM Ericsson Ab - SF-02420 Jorvas - Finland +Jyrki Holopainen +Oy LM Ericsson Ab +SF-02420 Jorvas +Finland ## To build: @@ -17,23 +17,23 @@ option `-inum` with `find` with the delete option after finding the inode with `ls -li` or else use a GUI to do it. Should you wish to try compiling it you might see something like: - NOTE: This will not compile when using modern compilers because - it relies on a compiler bug which was fixed in gcc 2.3.3 (a very - long time ago now). - rm -f \"\;main\(\)\{puts\(\"Hello\ World!\"\)\;\}char\*C=\".c - cp lmfjyh.c \"\;main\(\)\{puts\(\"Hello\ World!\"\)\;\}char\*C=\".c - cc -std=gnu90 -Wall -Wextra -pedantic -include stdio.h -O3 \ - \"\;main\(\)\{puts\(\"Hello\ World!\"\)\;\}char\*C=\".c -o lmfjyh - Undefined symbols for architecture arm64: - "_main", referenced from: - implicit entry/start for main executable - ld: symbol(s) not found for architecture arm64 - clang: error: linker command failed with exit code 1 (use -v to see invocation) - make: *** [lmfjyh] Error 1 - -and the bogus file will be: - - ";main(){puts("Hello World!");}char*C=".c +```sh +$ make all +NOTE: This will not compile when using modern compilers because +it relies on a compiler bug which was fixed in gcc 2.3.3 (a very +long time ago now). +rm -f \"\;main\(\)\{puts\(\"Hello\ World!\"\)\;\}char\*C=\".c +cp lmfjyh.c \"\;main\(\)\{puts\(\"Hello\ World!\"\)\;\}char\*C=\".c +cc -std=gnu90 -Wall -Wextra -pedantic -include stdio.h -O3 \ + \"\;main\(\)\{puts\(\"Hello\ World!\"\)\;\}char\*C=\".c -o lmfjyh +Undefined symbols for architecture arm64: + "_main", referenced from: + implicit entry/start for main executable +ld: symbol(s) not found for architecture arm64 +clang: error: linker command failed with exit code 1 (use -v to see invocation) +make: *** [lmfjyh] Error 1 +``` +and the bogus file will be `";main(){puts("Hello World!");}char*C=".c`. For an explanation of why this is see the author's remarks. @@ -41,14 +41,16 @@ For an explanation of why this is see the author's remarks. If you have gcc < 2.3.3: - ./lmfjyh +```sh +./lmfjyh +``` ## Judges' remarks: There's more than one way to get around disk quotas. :-) -## Author's remarks; +## Author's remarks: "Practical and efficient method of compressing source code". @@ -61,34 +63,36 @@ best with C-source code. As an example, I have taken a simple "Hello world!" program that should be familiar to all C-programmers. -Listing 1. A simple "Hello World" program: +#### Listing 1: A simple "Hello World" program - main() - { - puts("Hello World!"); - } - +```c +main() +{ + puts("Hello World!"); +} +``` ### Packing method -Normally a file name is used only to identify the file, -but this new revolutionary method introduces a totally new concept: -THE FILE NAME IS THE PROGRAM. There is no need to waste -valuable disk space to store source code. The program is -embedded in the file name, only a minor portion of it -is inside the file. +Normally a file name is used only to identify the file, but this new +revolutionary method introduces a totally new concept: THE FILE NAME IS THE +PROGRAM. There is no need to waste valuable disk space to store source code. The +program is embedded in the file name, only a minor portion of it is inside the +file. -Listing 2. Compressed "Hello world": +#### Listing 2: Compressed "Hello world" - - char*_=__FILE__; +```c +char*_=__FILE__; +``` -Listing 3. Code embedded in the file name: +#### Listing 3: Code embedded in the file name - - ";main(){puts("Hello World!");}char*C=".c +```c +";main(){puts("Hello World!");}char*C=".c +``` The sample program in listing 1 is 36 bytes long. By using the new @@ -97,12 +101,12 @@ bytes. In the example the compression ratio is 2:1. It is evident that the longer the program is, the better the compression ratio is. The maximum compression ratio in a UNIX environment is 254:16 which equals approximately to 16:1. By using the method a one -megabyte of source code can be compressed to 64 kilobytes. +megabyte of source code file can be compressed to 64 kilobytes. One might easily think that the program could be compressed to a single byte by writing a one character long preprocessor directive in the source file and defining the actual source code in the -command line, eg. 'cc hello.c -DX=main(){puts...'. With this +command line, eg. `cc hello.c -DX='main(){puts ...'`. With this method nothing is gained, since the compiling commands must be stored in a file, and that takes even more space than writing the code in a source file as presented in listing 1. @@ -111,12 +115,12 @@ code in a source file as presented in listing 1. ### Packing files in a UNIX environment In a UNIX environment it is possible to write almost any program by -including the code in file names. Since '/' is used to separate +including the code in file names. Since `/` is used to separate path components and cannot therefore exist in a file name, all features of C-language cannot be used. In C, the `/` is used as a division operator and it may also be a -part of a comment start and end identifier. This is, however, not a +part of a comment start and end identifier. This, however, is not a dangerous limitation, since practice has shown that comments are almost totally unnecessary. A real programmer can more easily understand pure source code, and misleading comments are @@ -127,7 +131,7 @@ when using integers. Large programs must be separated into small modules. This enforces people to write better programs, since monolithic programming style cannot be used. Program development will also be faster, no extra -code need not be recompiled after changes have been made. +code needs be recompiled after changes have been made. ### Usage with currently available tools @@ -136,30 +140,30 @@ I have tested how well this new method works with currently available programming tools. Any ANSI conforming C-compiler that runs under a REAL operating -system should be able to compile the code. (there may be problems -with some older UNIX variants) +system should be able to compile the code (there might be problems +with some older UNIX variants). -### Compilers: +### Compilers These worked: - gcc versions 2.0, 2.1, 2.3.2 (ld failed at AIX with gcc 2.1) - cc (HP-UX) - cc (VAX) +- gcc versions 2.0, 2.1, 2.3.2 (ld failed at AIX with gcc 2.1) +- cc (HP-UX) +- cc (VAX) These failed miserably: - cc (SunOs/Solaris) - could not start cpp properly - cc/xlc (AIX) - could not open source +- cc (SunOS/Solaris) - could not start cpp properly +- cc/xlc (AIX) - could not open source -### Other tools: +### Other tools -#### Debuggers: (tested at SunOs 4.1.2) +#### Debuggers: (tested at SunOS 4.1.2) -dbx - Quit with a very 'informative' error message: - "dbx: fatal error: Is a directory" +- dbx - Quit with a very 'informative' error message: + "dbx: fatal error: Is a directory" -gdb - Printed almost the same error message ":Is a directory". +- gdb - Printed almost the same error message ": Is a directory". It was, however, possible to step through the code but not list it. @@ -170,7 +174,7 @@ None of the lints tested environments were able to parse the file. ### Conclusions -The method can be used to compress any types of files, actually the +The method can be used to compress any types of files and the compression ratios are even better when compressing other files than C-source. For example plain text files may be compressed with INFINITE compression ratio. It is trivial task to compress a 100 diff --git a/1993/plummer/README.md b/1993/plummer/README.md index 9349e3dee..deeb689bc 100644 --- a/1993/plummer/README.md +++ b/1993/plummer/README.md @@ -1,22 +1,26 @@ # Best One Liner - Mark Plummer - 2901 Reckord Road - Fallston, MD, 21047 - USA +Mark Plummer +2901 Reckord Road +Fallston, MD, 21047 +USA ## To build: - make all +```sh +make all +``` ## To run: - ./plummer number arg +```sh +./plummer number arg +``` where: - number is a number (try 21701) - arg is any argument +- number is a number (try 21701) +- arg is any argument ### INABIAF - it's not a bug it's a feature :-) @@ -33,31 +37,31 @@ characters, and why? This program prints out all numbers up to a given number of digits on a single line. When the largest number is reached, the program starts again with 0. It takes two arguments: the first argument -specifies the number to start counting from and uses leading 0's to +specifies the number to start counting from and uses leading `0`s to indicate the number of digits, the second argument can be anything but must be present. Variable names are single characters chosen for their similarity to -other characters (O for 0, l for 1, S for 5 (in some fonts), and _ +other characters (O for 0, l for 1, S for 5 in some fonts, and _ for ... well nothing really, but it is easy to miss). To prevent the need for `strlen()`, the fact that argv is laid out sequentially is exploited (ie. `argv[i + 1] == argv[i] + strlen(argv[i]) + 1`). This is not portable (by the books), but it seems to work -everywhere I try (actually, for vms, that only holds for `i > 1`). +everywhere I try (actually, for VMS, that only holds for `i > 1`). Also, I depend on the fact that a carriage return causes the line -just written to be overwritten. lint (and most compilers) complain -that there is no control path leading to a return from main(). At +just written to be overwritten. `lint` (and most compilers) complain +that there is no control path leading to a return from `main()`. At 125 characters, it still fits on a single line (for those of us who don't mind ruining our eyes with 132 column screens). The first statement points the base of `l` (the argument vector) to be the first argument by incrementing it. It then assigns `O` to point to the character before the first character of the second -argument which also happens to be the null termination of the first +argument which also happens to be the NULL termination of the first argument. `*O` gets a `\r` assigned to it. Finally `0` is assigned to the first character of the second argument which has the effect of -null terminating the first argument after the carriage return had -removed its null termination. I really tried to make the last part +NULL terminating the first argument after the carriage return had +removed its NULL termination. I really tried to make the last part of that statement part of the original expression, but the best I could do was attach it with a comma (against the advice of K&R). The for loop runs the next for loop continuously (actually until @@ -66,7 +70,7 @@ counting). The next for loop is the meat of the program. In the initialization statement, the string pointed to by `l` (the first argument containing the digits used for counting followed by a `\r`) is printed, and `_` is started at the least significant digit in the -string. In the test portion, `_` is insured not to be past the +string. In the test portion, `_` is ensured not to be past the beginning of the string (the most significant digit), and the digit pointed to by `_` is incremented and checked to be sure that it _is_ greater than `9` (written here as `(S+*O+S)*S`). If the test fails, diff --git a/1993/schnitzi/README.md b/1993/schnitzi/README.md index 10d712b79..16ad80f14 100644 --- a/1993/schnitzi/README.md +++ b/1993/schnitzi/README.md @@ -9,11 +9,14 @@ USA ## To build: - make all +```sh +make all +``` [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) made this use `fgets()` -not `gets()` to make it safer and to prevent a warning with linking or at -runtime. Thank you Cody for your assistance! +not `gets()` to make it safer and to prevent an annoying warning with compiling +and/or linking and/or runtime, the latter of which is interspersed with the +output of the program itself. Thank you Cody for your assistance! ## To run: @@ -23,47 +26,55 @@ where: file a file containing some text -NOTE: this entry will segfault if the file cannot be opened. +### INABIAF - it's not a bug it's a feature! :-) + +This entry will segfault if the file cannot be opened. This is not a bug. ## Try: - ./schnitzi schnitzi.info - # ask some questions suggested by the author, noted below +```sh +./schnitzi schnitzi.info +# ask some questions suggested by the author, noted below +``` We also suggest you ask the program: - Who is Mark Schnitzus? +```sh +Who is Mark Schnitzus? +``` Notice how it still manages to answer the question despite there being an intentional spelling error there. Try feeding the program source to the program and ask both: - What is cat ? - What is cat? - +```sh +What is cat ? +What is cat? +``` ## Judges' remarks: After this program prints the contents of 'file', ask it some questions related to the text. -The author suggests the following questions when using schnitzi.info: +The author suggests the following questions when using +[schnitzi.info](schnitzi.info): - Who is Mark Schnitzius? - What exactly does this program do? - What language is it written in? - Has the Loch Ness monster really been captured? - Who was Hitler? - Were the NASA moon landings faked? - Is it true that Elvis is alive? - Do colorless green ideas sleep furiously? +- Who is Mark Schnitzius? +- What exactly does this program do? +- What language is it written in? +- Has the Loch Ness monster really been captured? +- Who was Hitler? +- Were the NASA moon landings faked? +- Is it true that Elvis is alive? +- Do colorless green ideas sleep furiously? We suggest you try using the body (minus the header and signature line) of a Usenet article. You might want to try something from alt.flame. :-) -NOTE: If you have a ' in the question this entry may fail. +NOTE: If you have a ' in the question this entry might fail. NOTE: The author may also be contacted at: marks@aldrin.ksc.nasa.gov. @@ -88,7 +99,7 @@ If you're curious as to how it works, I guess you could feed in the source as the input file and ask "How does this work?" at the prompt, but I'm not guaranteeing any results... -### Compilation notes: +### Compilation notes - The use of 'strcasecmp' may be non-standard. 'strcmp' can be substituted for it, with a slight performance penalty. @@ -97,14 +108,14 @@ it, with a slight performance penalty. argv[0], to hold the name of the executable. It is my understanding that this property of argv[0] is not guaranteed on some systems. -### Obfuscation: +### Obfuscation - It uses a hidden string to test for punctuation. - The layout, variable names, and expression format have been chosen in such a way as to cause visual confusion. -- It uses uses external 'system' calls to echo the text file and break up the +- It uses uses external `system()` calls to echo the text file and break up the question into individual words with a recursive call. - It uses a clever hack to simulate artificial intelligence. diff --git a/1993/vanb/README.md b/1993/vanb/README.md index 1d0569c28..8aa91aac5 100644 --- a/1993/vanb/README.md +++ b/1993/vanb/README.md @@ -1,14 +1,16 @@ # Most Irregular Expression - David Van Brackle - ISX Corporation - 1165 Northchase Parkway, Suite 120 - Marietta, GA 30067 - USA +David Van Brackle +ISX Corporation +1165 Northchase Parkway, Suite 120 +Marietta, GA 30067 +USA ## To build: - make all +```sh +make all +``` [Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) fixed this to work with clang. The problem was that the third arg to main() was not a `char **`. Instead @@ -18,42 +20,50 @@ right parameters. Thank you Cody for your assistance! ## To run: - ./vanb 'exp' - -where 'exp' is an octal expression +```sh +./vanb 'exp' +``` + +where `exp` is an octal expression. See below for how it can also have +hexadecimal and decimal numbers. ## Try: - ./vanb 1+1 +```sh +./vanb '1+1' - ./vanb 4+4 +./vanb '4+4' +``` +What happens if you use something other than valid digits? ## Judges' remarks: The octal expression may contain: - unary operators: +, - - binary operators +, -, *, /, % - hex numbers: x or X follow by hex digits - decimal numbers: d or D follow by decimal digits - octal numbers: octal digits - grouping: () - +``` +unary operators: +, - +binary operators +, -, *, /, % +hex numbers: x or X follow by hex digits +decimal numbers: d or D follow by decimal digits +octal numbers: octal digits +grouping: () +``` + No spaces are allowed in the expression. To avoid shell expansion, one should surround the expression in single quotes. It is a good thing that this program consists of only one expression, otherwise it might become hard to understand. :-) -## Author's remarks +## Author's remarks: The program does no error checking - erroneous expressions will -produce spurious results. Note that unary '-' is an operator. Thus, -decimal -46 would be entered as -d46 and not d-46. +produce spurious results. Note that unary `-` is an operator. Thus, +decimal `-46` would be entered as `-d46` and not `d-46`. -What Makes This Program Special: +### What Makes This Program Special: 0. Of course, the fact that the program takes input and produces output in octal, rather than a more useful system like decimal, makes it "special". @@ -68,133 +78,145 @@ printf string. 4. The variables are given names which cause visual confusion with the octal constants. -5. The program is formatted like a roman numeral 8. The significance of 8 is -obvious. I chose roman numerals because it is a numbering system even more +5. The program is formatted like a Roman numeral 8. The significance of 8 is +obvious. I chose Roman numerals because it is a numbering system even more arcane than octal. It's not very 'deceptive', but it's difficult to deceptively -format a program which has no explicit control structures (other than ?:'s). +format a program which has no explicit control structures (other than `?:`s). 6. Many simple tasks are done many times. I tried to do these differently each time, to make the program harder to understand. -How It Works: +### How It Works: -It's a recursive descent parser, calling main -for all of its recursion. O2 is a state variable, telling main +It's a recursive descent parser, calling `main` +for all of its recursion. `O2` is a state variable, telling main what grammar non-terminal to parse. `**O7` is the next character. `O3` is an intermediate result. Whenever you see a construct like: +``` !(expression with O2)? +``` -it's decrementing & testing O2 to see what state it's in. Comparisons +it's decrementing & testing `O2` to see what state it's in. Comparisons involving `**O7` and octal constants are looking for certain characters. -Here's the grammar ('e' denotes the empty string) : +Here's the grammar `('e'` denotes the empty string) : - ::= - ::= + | - | e - ::= - ::= * | / | % | e - ::= + | - | ( | d | D | x | X | - ::= ) - ::= [0-9] | e - ::= [0-9] | [A-F] | [a-f] | e - ::= [0-7] | e - +``` + ::= + ::= + | - | e + ::= + ::= * | / | % | e + ::= + | - | ( | d | D | x | X | + ::= ) + ::= [0-9] | e + ::= [0-9] | [A-F] | [a-f] | e + ::= [0-7] | e +``` Here's how the grammar nonterminals map to octal state numbers: - is 012 - is 011 - is 010 - is 07 - is 06 - is 013 - is 04 - is 05 - is 03 +``` + is 012 + is 011 + is 010 + is 07 + is 06 + is 013 + is 04 + is 05 + is 03 +``` Here's a version of the program before it got formatted into the VIII, -augmented with comments showing where each state begins. N1 and N2 are +augmented with comments showing where each state begins. `N1` and `N2` are notes: +```c +#define O5 main +O5(O2,O7,O3)char**O7; +{ + return +/* N1 */ !(O2+=~01+01) ? + 00: +/* N2 */ !(O2-=02>01) ? + printf("\045\157\012",O5(012,O7+01,00)): +/* O */ !(O2-=02>>01) ? + (**O7<=067 && **O7>057 ? O5(03,O7,*(*O7)++-060+010*O3):O3): +/* D */ !(O2-=-O3-~O3) ? + (072>**O7 && 060<=**O7 ? O5(04,O7,012*O3-060+*(*O7)++):O3): +/* X */ !(O2-=!O3+!!O3) ? + (**O7>057 && **O7<=071 ? O5(05,O7,*(*O7)+++O3*020-060): + **O7<=0106 && 0101<=**O7 ? O5(05,O7,020*O3+*(*O7)++-067): + 0140<**O7 && **O7<0147 ? O5(05,O7,-0127+*(*O7)+++020*O3):O3): +/* F */ !(O2-=02-01) ? + (**O7==050 ? 050**++*O7,O5(013,O7,O5(012,O7,00)): + **O7<056 && 054<**O7 ? 055**++*O7,-O5(06,O7,00): + 054>**O7 && 052<**O7 ? 050**(*O7)++,O5(06,O7,00): + !(**O7^0170)||!(0130^**O7) ? *++*O7,O5(05,O7,00): + **O7==0144||**O7==0104 ? ++*O7,O5(04,O7,00):O5(03,O7,00)): +/* T' */ !--O2 ? + (**O7==052 ? O5(07,O7,O3*(*++*O7,O5(06,O7,00))): + !(045-**O7) ? O5(07,O7,O3%(03+(*O7)++,O5(06,O7,00))): + !(**O7^057) ? O5(07,O7,O3/(03-*++*O7,O5(06,O7,00))):O3): +/* T */ !(O2+=01-02) ? + O5(07,O7,O5(06,O7,00)): +/* E' */ !(O2+=-02/02) ? + (!(**O7-053)?O5(011,O7,O3+(++*O7,O5(010,O7,00))): + !(055^**O7) ? O5(011,O7,O3-(03+*(*O7)++,O5(010,O7,00))):O3): +/* E */ !(O2-=0563&0215) ? + O5(011,O7,O5(010,O7,00)): +/* C */ (++*O7,O3); +} +``` - #define O5 main - O5(O2,O7,O3)char**O7; - { - return - /* N1 */ !(O2+=~01+01) ? - 00: - /* N2 */ !(O2-=02>01) ? - printf("\045\157\012",O5(012,O7+01,00)): - /* O */ !(O2-=02>>01) ? - (**O7<=067 && **O7>057 ? O5(03,O7,*(*O7)++-060+010*O3):O3): - /* D */ !(O2-=-O3-~O3) ? - (072>**O7 && 060<=**O7 ? O5(04,O7,012*O3-060+*(*O7)++):O3): - /* X */ !(O2-=!O3+!!O3) ? - (**O7>057 && **O7<=071 ? O5(05,O7,*(*O7)+++O3*020-060): - **O7<=0106 && 0101<=**O7 ? O5(05,O7,020*O3+*(*O7)++-067): - 0140<**O7 && **O7<0147 ? O5(05,O7,-0127+*(*O7)+++020*O3):O3): - /* F */ !(O2-=02-01) ? - (**O7==050 ? 050**++*O7,O5(013,O7,O5(012,O7,00)): - **O7<056 && 054<**O7 ? 055**++*O7,-O5(06,O7,00): - 054>**O7 && 052<**O7 ? 050**(*O7)++,O5(06,O7,00): - !(**O7^0170)||!(0130^**O7) ? *++*O7,O5(05,O7,00): - **O7==0144||**O7==0104 ? ++*O7,O5(04,O7,00):O5(03,O7,00)): - /* T' */ !--O2 ? - (**O7==052 ? O5(07,O7,O3*(*++*O7,O5(06,O7,00))): - !(045-**O7) ? O5(07,O7,O3%(03+(*O7)++,O5(06,O7,00))): - !(**O7^057) ? O5(07,O7,O3/(03-*++*O7,O5(06,O7,00))):O3): - /* T */ !(O2+=01-02) ? - O5(07,O7,O5(06,O7,00)): - /* E' */ !(O2+=-02/02) ? - (!(**O7-053)?O5(011,O7,O3+(++*O7,O5(010,O7,00))): - !(055^**O7) ? O5(011,O7,O3-(03+*(*O7)++,O5(010,O7,00))):O3): - /* E */ !(O2-=0563&0215) ? - O5(011,O7,O5(010,O7,00)): - /* C */ (++*O7,O3); - } - -Note N1: It should never enter this state, unless the user invokes the +Note `N1`: It should never enter this state, unless the user invokes the program with no parameters, in which case it just returns 0. -Note N2: Since the program is properly invoked with 1 parameter, this is +Note `N2`: Since the program is properly invoked with 1 parameter, this is the first state it will go into. This state just invokes -printf, and sends the parser to state 012 (which is ``). +printf, and sends the parser to state `012` (which is ``). -The E and T states work like this: +The `E` and `T` states work like this: - int e(){ return eprime( t() ); } +```c +int e(){ return eprime( t() ); } +``` -The E' and T' states work like this: +The `E'` and `T'` states work like this: +```c +int eprime( int intermediate ) +{ + if( ch == '+' ) + { + ch = nextchar(); + return eprime( intermediate + t() ); + } + else return intermediate; +} +``` - int eprime( int intermediate ) - { - if( ch == '+' ) - { - ch = nextchar(); - return eprime( intermediate + t() ); - } - else return intermediate; - } +The `D`, `X` and `O` states work like this (they assume that they're initially +called with `0`): -The D, X and O states work like this (they assume that they're initially -called with 0): +```c +int octal( int intermediate ) +{ + if( ch>='0' && ch<='7' ) + { + intermediate = intermediate * 8 + ch - '0'; + ch = nextchar(); + return octal( intermediate ); + } + else return intermediate; +} - int octal( int intermediate ) - { - if( ch>='0' && ch<='7' ) - { - intermediate = intermediate * 8 + ch - '0'; - ch = nextchar(); - return octal( intermediate ); - } - else return intermediate; - } +``` -F and C work similarly. +`F` and `C` work similarly. ## Copyright and CC BY-SA 4.0 License: