Merge pull request #1450 from xexyl/westley2001
This commit is contained in:
16 files changed
+259
-144
No files matched your search
@@ -145,9 +145,9 @@ ${PROG}: ${PROG}.c
|
||||
|
||||
|
||||
${PROG}.ten: ${PROG}.ten.c
|
||||
@echo "WARNING: ${PROG}.ten.c must be compiled as 32-bit to use with the entry itself;"
|
||||
@echo "this is because the program works on 32-bit binaries. If you cannot use -m32 this"
|
||||
@echo "will NOT work!"
|
||||
@echo "WARNING: ${PROG}.ten.c must be compiled as a 32-bit ELF binary to use with"
|
||||
@echo "the entry itself; this is because the program works on 32-bit ELF binaries."
|
||||
@echo "If you cannot use -m32 this will NOT work!"
|
||||
@echo
|
||||
@echo "If you want to use it where this is not possible e.g. with a Mac, say to"
|
||||
@echo "use by itself, try:"
|
||||
@@ -165,9 +165,9 @@ ${PROG}.ten.64: ${PROG}.ten.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||
|
||||
${PROG}.bed: ${PROG}.bed.c
|
||||
@echo "WARNING: ${PROG}.bed.c must be compiled as 32-bit to use with the entry itself;"
|
||||
@echo "this is because the program works on 32-bit binaries. If you cannot use -m32 this"
|
||||
@echo "will NOT work!"
|
||||
@echo "WARNING: ${PROG}.bed.c must be compiled as a 32-bit ELF binary to use with"
|
||||
@echo "the entry itself; this is because the program works on 32-bit ELF binaries."
|
||||
@echo "If you cannot use -m32 this will NOT work!"
|
||||
@echo
|
||||
@echo "If you want to use it where this is not possible e.g. with a Mac, say to"
|
||||
@echo "use by itself, try:"
|
||||
|
||||
+28
-15
@@ -28,20 +28,21 @@ For more detailed information see [2001 anonymous in bugs.md](/bugs.md#2001-anon
|
||||
```sh
|
||||
./try.sh
|
||||
|
||||
./anonymous anonymous.bed # if able to use -m32
|
||||
./anonymous anonymous.bed # if able to compile as a 32-bit (-m32) ELF binary
|
||||
```
|
||||
|
||||
NOTE: if the 32-bit version cannot be compiled the script will at least compile
|
||||
[anonymous.ten](anonymous.ten.c) as a 64-bit program and run it directly.
|
||||
[anonymous.ten](anonymous.ten.c) as a 64-bit program and run it directly. If it
|
||||
can be compiled but it's not an ELF binary the program is likely to crash.
|
||||
|
||||
For fun and so that there's another program that is a bit different (it uses a `char
|
||||
*[]` array for example) that this program will still work on:
|
||||
|
||||
```sh
|
||||
make anonymous.bed # if able to use -m32
|
||||
make anonymous.bed # if able to compile as 32-bit (-m32) ELF binary
|
||||
./anonymous anonymous.bed
|
||||
|
||||
make anonymous.bed.64 # if unable to use -m32
|
||||
make anonymous.bed.64 # if unable to compile as a 32-bit (-m32) ELF binary
|
||||
./anonymous.bed.64
|
||||
```
|
||||
|
||||
@@ -61,7 +62,7 @@ that :-(
|
||||
If the program cannot be run (for instance under macOS as an ELF file) then
|
||||
the program will fail to execute it and might not even touch it.
|
||||
|
||||
This is supposed to happen. As is written in the
|
||||
These are supposed to happen. As is written in the
|
||||
[The Jargon File](http://catb.org/jargon/html/F/feature.html):
|
||||
|
||||
```
|
||||
@@ -79,6 +80,9 @@ no longer known exactly what is supposed to happen and possibly that the
|
||||
modification might not be entirely correct for that reason though it does appear
|
||||
to be correct.
|
||||
|
||||
It appears that the corruption happens only if the modification fails in the
|
||||
middle of doing so so that might be why it's not yet been observed.
|
||||
|
||||
|
||||
## Judges' remarks:
|
||||
|
||||
@@ -93,10 +97,13 @@ run x86 programs on any machine (x86 or otherwise).
|
||||
|
||||
I have included a simple [10 Green
|
||||
Bottles](https://www.bbc.co.uk/teach/school-radio/nursery-rhymes-ten-green-bottles/zncyt39)
|
||||
[program](anonymous.ten.c) (try `make anonymous.ten`), meant to be compiled in 32-bit.
|
||||
[program](anonymous.ten.c) (try `make anonymous.ten`), meant to be compiled as a
|
||||
32-bit ELF binary.
|
||||
|
||||
The program `anonymous.ten`, and its source (dull) are included as data
|
||||
files.
|
||||
|
||||
|
||||
### Warning
|
||||
|
||||
Note that the translator screws around with the binary you run on it and *might*
|
||||
@@ -114,7 +121,7 @@ generates a translation for an entire basic block of subject code. Having
|
||||
translated a block once, the target code generated will be stored for the
|
||||
duration that the program is running, so as a program runs its performance will
|
||||
improve, as it hits cached blocks. This can be clearly observed in the example
|
||||
program, [anonymous.ten](anonymous.ten.c) which must be compiled as a 32-bit
|
||||
program, [anonymous.ten](anonymous.ten.c) which must be compiled as a 32-bit ELF
|
||||
binary.
|
||||
|
||||
### Target Library Linking:
|
||||
@@ -136,8 +143,10 @@ There are various problems raised when attempting to run little
|
||||
[PPC](https://en.wikipedia.org/wiki/PowerPC). These problems are dealt
|
||||
with in a manner that is entirely transparent to the user.
|
||||
|
||||
|
||||
### Configuration:
|
||||
|
||||
|
||||
#### Warnings:
|
||||
|
||||
By default the build script should compile the program with a set of
|
||||
@@ -149,6 +158,7 @@ error, or if the program generates any further error when compiled using
|
||||
your C compiler please remove the `-Dwarning='-Dprocessor'` line and the
|
||||
`$$warning` from the compiler invocation.
|
||||
|
||||
|
||||
### Optimization
|
||||
|
||||
The build script contains a `-O1` switch for the compiler. Increasing
|
||||
@@ -156,6 +166,7 @@ the optimization level will make the program run *slower*, while
|
||||
compiling the program without any optimization will allow it to run
|
||||
*faster*.
|
||||
|
||||
|
||||
### Obfuscation
|
||||
|
||||
The most obvious part of the obfuscation is probably the mess of `#define`s at the
|
||||
@@ -170,7 +181,7 @@ not contained within the source code but instead is passed in on the command
|
||||
line.
|
||||
|
||||
Buried under all this, and the fact that the entire program is just a
|
||||
call to `exit()`, there are some nice subtle little obfuscations. For
|
||||
call to `exit(3)`, there are some nice subtle little obfuscations. For
|
||||
example, you may notice that there are a couple of macros that use the
|
||||
`##` preprocessor operator to build pairs of functions. One of these
|
||||
macros is used to build pairs of functions of which only one has
|
||||
@@ -179,11 +190,12 @@ global state, and the other doesn't.
|
||||
|
||||
There is also quite a nice trick where I wave a magic wand, and a chunk of code
|
||||
which should only be run when the program is run for the first time (setting the
|
||||
[PC / IP](https://en.wikipedia.org/wiki/Program_counter) to point at `main()`,
|
||||
etc) gets turned into a `frog^M^M^M^Mstring`. The C compiler sees a string by
|
||||
[PC / IP](https://en.wikipedia.org/wiki/Program_counter) to point at `main()`
|
||||
etc.) gets turned into a <strike>frog</strike>string. The C compiler sees a string by
|
||||
itself in the code, thinks "yup, that's a valid C expression", and quietly moves
|
||||
on to the next line of code.
|
||||
|
||||
|
||||
### Limitations
|
||||
|
||||
Due to space limitations only a handful of instructions are supported; these
|
||||
@@ -200,19 +212,20 @@ turn up - yes the program is unsafe, but it's pretty cool anyway.
|
||||
Despite all this, the translator is not exclusively limited to running the
|
||||
[anonymous.ten](anonymous.ten.c) program. Other trivial **_x86_** programs may
|
||||
run on the translator \- and I have successfully run a wide range of "Hello
|
||||
World" programs, including one of last years IOCCC winners,
|
||||
World" programs, including one of last year's IOCCC winners,
|
||||
[tomx](/2000/tomx/tomx.c).
|
||||
|
||||
|
||||
### Complete Program
|
||||
|
||||
The fact that the program makes calls to `system()` and `execv()` may imply that
|
||||
The fact that the program makes calls to `system(3)` and `execv(3)` may imply that
|
||||
it is not a complete program in its own right, as it relies on other programs.
|
||||
The call to `system()` is a call to ask gcc to recompile the translator with a
|
||||
new set of switches, and the call to `execv()` asks for the newly compiled
|
||||
The call to `system(3)` is a call to ask gcc to recompile the translator with a
|
||||
new set of switches, and the call to `execv(3)` asks for the newly compiled
|
||||
program to be executed. I would point out that almost every other entry to this
|
||||
competition also require a C compiler (well, the published winners at any rate,
|
||||
and I recognize that a few don't). There is little real difference between this
|
||||
program and one like last years entry [dhyang](/2000/dhyang/dhyang.c); both are
|
||||
program and one like last year's entry [dhyang](/2000/dhyang/dhyang.c); both are
|
||||
just C programs that generate C code as their output.
|
||||
|
||||
Enjoy and thanks!
|
||||
|
||||
+5
-2
@@ -114,8 +114,8 @@ OBJ= ${PROG}.o
|
||||
DATA=
|
||||
TARGET= ${PROG}
|
||||
#
|
||||
ALT_OBJ=
|
||||
ALT_TARGET=
|
||||
ALT_OBJ= ${PROG}.alt.o
|
||||
ALT_TARGET= ${PROG}.alt
|
||||
|
||||
|
||||
#################
|
||||
@@ -138,6 +138,9 @@ ${PROG}: ${PROG}.c
|
||||
alt: data ${ALT_TARGET}
|
||||
@${TRUE}
|
||||
|
||||
${PROG}.alt: ${PROG}.alt.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
|
||||
+30
-18
@@ -4,6 +4,9 @@
|
||||
make
|
||||
```
|
||||
|
||||
There is an alternate version with vi(m) key movements. See [alternate
|
||||
code](#alternate code) below.
|
||||
|
||||
|
||||
## To use:
|
||||
|
||||
@@ -12,14 +15,24 @@ make
|
||||
```
|
||||
|
||||
|
||||
### Try:
|
||||
## Alternate code:
|
||||
|
||||
This alternate version adds to the movement keys `l` for right, `h` for left and
|
||||
`k` for straight.
|
||||
|
||||
|
||||
### Alternate build:
|
||||
|
||||
|
||||
```sh
|
||||
echo "Do or do not. There is no try."
|
||||
make alt
|
||||
```
|
||||
|
||||
Make sure to hit `q` to exit or else your terminal will be messed up (to restore
|
||||
it you can try `stty sane` or `reset`).
|
||||
### Alternate use:
|
||||
|
||||
```sh
|
||||
./ctk.alt
|
||||
```
|
||||
|
||||
|
||||
## Judges' remarks:
|
||||
@@ -32,20 +45,19 @@ This is, of course, another of the retro games.
|
||||
|
||||
## Author's remarks:
|
||||
|
||||
This is a game based on an Apple ][ Print Shop Companion [Easter
|
||||
egg][1] named 'DRIVER', in which the goal is to drive as fast as
|
||||
you can down a long twisty highway without running off the
|
||||
road. Use `,./`, `[ ]`, or `bnm` to go left, straight, and
|
||||
right respectively. Use `1234` to switch gears. `q` quits. The
|
||||
faster you go and the thinner the road is, the more points you
|
||||
get. Most of the obfuscation is in the nonsensical if statements
|
||||
among other things. It works best on the Linux console: you
|
||||
get engine sound (!) and the * Lock keyboard lights tell you
|
||||
what gear you're in (none lit=4th). The `q` argument (no
|
||||
leading `-`) will silence the sound. It won't work on a terminal
|
||||
smaller than 80x24, but it works fine with more (try it in an
|
||||
XTerm with the "Unreadable" font and the window maximized
|
||||
vertically!).
|
||||
This is a game based on an [Apple
|
||||
II](https://en.wikipedia.org/wiki/Apple_II_series) [Print Shop
|
||||
Companion](https://en.wikipedia.org/wiki/The_Print_Shop) [Easter egg][1] named
|
||||
'DRIVER', in which the goal is to drive as fast as you can down a long twisty
|
||||
highway without running off the road. Use `,./`, `[ ]`, or `bnm` to go left,
|
||||
straight, and right respectively. Use `1234` to switch gears. `q` quits. The
|
||||
faster you go and the thinner the road is, the more points you get. Most of the
|
||||
obfuscation is in the nonsensical if statements among other things. It works
|
||||
best on the Linux console: you get engine sound (!) and the * Lock keyboard
|
||||
lights tell you what gear you're in (none lit=4th). The `q` argument (no
|
||||
leading `-`) will silence the sound. It won't work on a terminal smaller than
|
||||
80x24, but it works fine with more (try it in an XTerm with the "Unreadable"
|
||||
font and the window maximized vertically!).
|
||||
|
||||
[1]: https://en.wikipedia.org/wiki/Easter_egg_(media)#In_computing
|
||||
|
||||
|
||||
+1
-1
@@ -22,4 +22,4 @@ SIG_IGN);printf("\e[0q\ecScore: %u\n",s);system("stty echo -cbreak");}int main
|
||||
int)0x756E696C||C==(int)0x6C696E75);srand(getpid());system("stty -echo cbreak"
|
||||
);h(0);u(14);for(;;)switch(getchar()){case 113:return 0;case 91:case 98:c(44,k
|
||||
=-1);case 32:case 110:c(46,k=0);case 93:case 109:c(47,k=1);c(49,h(0));c(50,h(1
|
||||
));c(51,h(2));c(52,h(3));}}
|
||||
));c(51,h(2));c(52,h(3));}e();}
|
||||
+35
-20
@@ -4,6 +4,9 @@
|
||||
make
|
||||
```
|
||||
|
||||
There is an alternate version based on the author's remarks. See [alternate
|
||||
code](#alternate-code) below for more details.
|
||||
|
||||
|
||||
### Bugs and (Mis)features:
|
||||
|
||||
@@ -27,16 +30,28 @@ For more detailed information see [2001 dgbeards in bugs.md](/bugs.md#2001-dgbea
|
||||
|
||||
The author provided a way to speed it up a bit and also how to make it so it
|
||||
doesn't crash on losing. The idea that it crashes on losing was too good to
|
||||
lose but this alternate version has the former change.
|
||||
lose but this alternate version has the former change. If you wish to remove
|
||||
this you can look at the author's remarks and make the change.
|
||||
|
||||
To compile:
|
||||
|
||||
### Alternate build:
|
||||
|
||||
```sh
|
||||
make alt
|
||||
```
|
||||
|
||||
Use `dgbeards.alt` as you would `dgbeards` above. Can you find a flaw in this
|
||||
version that the author did not note?
|
||||
|
||||
### Alternate use:
|
||||
|
||||
```sh
|
||||
./dgbeards.alt
|
||||
```
|
||||
|
||||
|
||||
### Try:
|
||||
|
||||
See if you can figure out how to make the computer always lose ('win' :-) ).
|
||||
It's a very simple thing to do. Read the author's remarks for clues.
|
||||
|
||||
This game crashes if it loses.
|
||||
|
||||
@@ -48,12 +63,6 @@ That's not a bug, that's a feature.
|
||||
```
|
||||
|
||||
|
||||
### Try:
|
||||
|
||||
See if you can figure out how to make the computer always lose. It's a very
|
||||
simple thing to do. Read the author's remarks for clues.
|
||||
|
||||
|
||||
## Judges' remarks:
|
||||
|
||||
This is probably the worst AI we've ever seen. So, then, why did
|
||||
@@ -100,6 +109,7 @@ can be captured.
|
||||
|
||||
5. Castling is not allowed.
|
||||
|
||||
|
||||
#### Q: How do you use this program?
|
||||
|
||||
A: The program is fairly straightforward. When you start the program,
|
||||
@@ -128,6 +138,7 @@ You can also specify a command line argument of a single digit to change
|
||||
the search depth of the program. If no argument is specified, it
|
||||
defaults to a depth of 3.
|
||||
|
||||
|
||||
#### Q: Are there any limitations in your program?
|
||||
|
||||
A: Yes. The first of the limitations is that you can only play legal
|
||||
@@ -141,6 +152,7 @@ losses several moves ahead, but does not announce the end of a game or
|
||||
the winner. Given the existing code it is easy to do this, but it was
|
||||
deemed unnecessary fluff.
|
||||
|
||||
|
||||
#### Q: What is the playing strength of this program?
|
||||
|
||||
A: Playing strength is a relative term. Relative to other computer
|
||||
@@ -163,15 +175,16 @@ In such positions, it will often just shuffle pieces around aimlessly
|
||||
until a tactical exchange presents itself.
|
||||
|
||||
A small amount of randomness has been added to make the program a more
|
||||
interesting opponent. To avoid a call to `srand()`, `rand()` and the
|
||||
extra code for the required include files, the `time()` function is used as
|
||||
interesting opponent. To avoid a call to `srand(3)`, `rand(3)` and the
|
||||
extra code for the required include files, the `time(3)` function is used as
|
||||
the source of random data. It is a slow function, and since it is
|
||||
executed inside the search loop, there is a significant performance
|
||||
decrease. To make it faster, replace the `time()` call with `rand()` and add
|
||||
decrease. To make it faster, replace the `time(3)` call with `rand(3)` and add
|
||||
the line `srand(time(0));` to the beginning of `main()`. I used the more
|
||||
inefficient `time()` function to illustrate a different (and somewhat
|
||||
inefficient `time(3)` function to illustrate a different (and somewhat
|
||||
obfuscated?) way of generating random numbers.
|
||||
|
||||
|
||||
#### Q: Why is this program obfuscated?
|
||||
|
||||
A: Here are several reasons:
|
||||
@@ -200,7 +213,7 @@ hide the real purpose of strings. These layers of obscurity cannot be
|
||||
penetrated by just preprocessing and beautifying the program.
|
||||
|
||||
Fifth, various small obfuscations have been used in places all over the
|
||||
program. Short circuit evaluation is used as a substitute for if()
|
||||
program. Short circuit evaluation is used as a substitute for `if()`
|
||||
statements in some places. The ternary operator is used. In the
|
||||
author's opinion, use of the ternary operator is almost always a strong
|
||||
argument for employee turnover.
|
||||
@@ -211,6 +224,7 @@ implements is an obscure game. Casual inspection of the program might
|
||||
lead one to believe that it is an implementation of classic chess, but
|
||||
this is not so.
|
||||
|
||||
|
||||
#### Q: What about the compiler warnings?
|
||||
|
||||
A: When compiled with `gcc -Wall`, the compiler generated the following
|
||||
@@ -226,7 +240,7 @@ value computed is not used
|
||||
|
||||
The `value computed is not used` warning happens because I use the `&&`
|
||||
operator and take advantage of short circuit evaluation instead of using
|
||||
an if() statement.
|
||||
an `if()` statement.
|
||||
|
||||
The `suggest parentheses...` warnings are given because of expressions
|
||||
that depend on operator precedence details in the C language.
|
||||
@@ -235,6 +249,7 @@ Eliminating these warnings would reduce obfuscation.
|
||||
The other warnings are there because it would require more code to
|
||||
eliminate them and that can't be done given the size limit.
|
||||
|
||||
|
||||
#### Q: Why does this program crash when it loses?
|
||||
|
||||
A: What better way to admit defeat? The author thought this was
|
||||
@@ -245,12 +260,12 @@ obfuscated program.
|
||||
[Judge's note: This was followed by a description of the bug, and
|
||||
the comment:]
|
||||
|
||||
(Note, if this program wins, the author thinks it would be good to leave
|
||||
Note, if this program wins, the author thinks it would be good to leave
|
||||
this information out of the remarks and encourage others to try and
|
||||
figure it out for themselves)
|
||||
figure it out for themselves.
|
||||
|
||||
[should you be too lazy to figure it out yourself, here's the author's
|
||||
fix.]
|
||||
[Should you be too lazy (or time-efficient or affected by 'real life' :-) ) to
|
||||
figure it out yourself, here's the author's fix.]
|
||||
|
||||
This bug can be fixed in a number of ways, but there is a way that adds only one
|
||||
byte to the source code. In the statement `s=(e=-V(n-1,o))>s?Y=G,e:s;` change
|
||||
|
||||
@@ -132,7 +132,7 @@ P V(P n, P o) {
|
||||
R s;
|
||||
}
|
||||
main(P db, F *bd[]){
|
||||
srand(0);
|
||||
srand(time(0));
|
||||
N o[500];
|
||||
F T[256];
|
||||
|
||||
|
||||
+10
-9
@@ -12,13 +12,6 @@ make
|
||||
```
|
||||
|
||||
|
||||
### Try:
|
||||
|
||||
```sh
|
||||
echo "Do or do not. There is no try."
|
||||
```
|
||||
|
||||
|
||||
## Judges' remarks:
|
||||
|
||||
You are in a maze of twisty little passages, all alike.
|
||||
@@ -33,6 +26,11 @@ expect that from something this small.
|
||||
Of particular interest: Go ahead, run it through the preprocessor. You
|
||||
*still* won't see the words that are used in the game.
|
||||
|
||||
If you run it through a beautifier you might cause a crash as most of the
|
||||
whitespace is significant. Also, if you attempt to change one character
|
||||
identifiers to longer names expect problems. Even swapping the `Y` and `Z` can
|
||||
cause problems. Go ahead, try it! :-)
|
||||
|
||||
|
||||
## Author's remarks:
|
||||
|
||||
@@ -54,7 +52,7 @@ out by typing "`get lamp`", then use the direction words "`left`",
|
||||
"`right`", "`forward`", and "`back`" to explore the caves. Note that
|
||||
these words can refer to different passages depending on which way
|
||||
you're facing. "`back`" always takes you back the way you came.
|
||||
Type "quit" to quit.
|
||||
Type "`quit`" to quit.
|
||||
|
||||
The maze is randomly generated each time you play. The algorithm
|
||||
ensures that you start at least 6 hops away from the exit. All
|
||||
@@ -81,7 +79,7 @@ Why I think this program is obfuscated:
|
||||
* Where are all the messages? The game is downright chatty for
|
||||
only having two string literals (`"%d \n"` and `"Y\n : ! ,.?>"`).
|
||||
|
||||
* There is exactly one loop in the program, a for loop, and it is
|
||||
* There is exactly one loop in the program, a `for` loop, and it is
|
||||
clearly the product of a deranged mind. Running the
|
||||
preprocessor only makes it worse.
|
||||
|
||||
@@ -124,6 +122,9 @@ in the source code.)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### GAME STRATEGY SPOILER
|
||||
|
||||
The trick, of course, is to drop items in empty rooms to mark them. That way
|
||||
|
||||
+6
-22
@@ -5,32 +5,12 @@ make
|
||||
```
|
||||
|
||||
|
||||
### Bugs and (Mis)features:
|
||||
|
||||
The current status of this entry is:
|
||||
|
||||
```
|
||||
STATUS: known bug - please help us fix
|
||||
```
|
||||
|
||||
For more detailed information see [2001 ollinger in bugs.md](/bugs.md#2001-ollinger).
|
||||
|
||||
|
||||
## To use:
|
||||
|
||||
```sh
|
||||
./ollinger integer
|
||||
```
|
||||
|
||||
This program will very likely crash or do something else without an arg.
|
||||
|
||||
This is supposed to happen. As is written in the
|
||||
[The Jargon File](http://catb.org/jargon/html/F/feature.html):
|
||||
|
||||
```
|
||||
That's not a bug, that's a feature.
|
||||
```
|
||||
|
||||
|
||||
### Try:
|
||||
|
||||
@@ -49,6 +29,7 @@ Do get lost in the programs line of thought! :-)
|
||||
|
||||
## Author's remarks:
|
||||
|
||||
|
||||
### What's this?
|
||||
|
||||
What do you see? On the left, you will see an enumeration of all successive
|
||||
@@ -58,13 +39,15 @@ primes. The big diagonals from right to left are used to erase composed numbers.
|
||||
When no diagonal crosses a number, then the left cell take value 1 and the
|
||||
number is prime.
|
||||
|
||||
The parallel version of this algorithm works in real time n. This C
|
||||
The parallel version of this algorithm works in real time `n`. This C
|
||||
sequential version is slower as it works in `O(n*log n)`. But you have some
|
||||
nice picture instead... the cost is a constant number of operation for each
|
||||
character printed on the screen.
|
||||
|
||||
|
||||
### Why did I write this ?
|
||||
|
||||
|
||||
Let's just quote the [FAQ](/faq.md):
|
||||
|
||||
Q: Are there types of entries that are submitted so frequently that the
|
||||
@@ -107,6 +90,7 @@ Unbeaten for 12 years and counting...
|
||||
I think this is enough motivation for trying to submit a program which uses
|
||||
some complex state machine/table to generate small primes and print them.
|
||||
|
||||
|
||||
### The way it works
|
||||
|
||||
This program simply prints the space-time diagram of some particular
|
||||
@@ -116,7 +100,7 @@ It is an optimization of an old automaton for recognizing primes designed
|
||||
by [Fischer](http://richardallenfischer.com) in 1965.
|
||||
|
||||
The table of the automaton is encoded into the string `e` and consists of
|
||||
345 transitions of the kind ff(left,middle,right)`. This encoding into `e`
|
||||
345 transitions of the kind `ff(left,middle,right)`. This encoding into `e`
|
||||
is obfuscated to reduce its size, restrict it to characters 32 to 127 and
|
||||
guarantee a constant time.
|
||||
|
||||
|
||||
@@ -41,9 +41,7 @@ That's not a bug, that's a feature.
|
||||
### Try:
|
||||
|
||||
```sh
|
||||
./schweikh foo 'f??'; echo $?
|
||||
./schweikh 'best short program' '??st*o**p?*'; echo $?
|
||||
./schweikh bar 'f??'; echo $?
|
||||
./try.sh
|
||||
```
|
||||
|
||||
|
||||
@@ -64,7 +62,7 @@ the whole string, so you may want to use `*` at the beginning and end of the
|
||||
pattern if you are looking for something in the middle.
|
||||
|
||||
You can use it for your shell scripting needs similar to a silent grep
|
||||
(and without stdout redirected to `/dev/null`):
|
||||
(and without `stdout` redirected to `/dev/null`):
|
||||
|
||||
```sh
|
||||
if prog "${VARIABLE}" '<glob>'; then
|
||||
@@ -83,15 +81,15 @@ All obfuscation is obviously in the recursive `m()` function, an 86
|
||||
character glob pattern evaluator, returning nonzero for a match:
|
||||
|
||||
* Just a single complex return expression.
|
||||
* Nested ternary operator `?:` to save on if/else verbosity.
|
||||
* Short circuiting `&&` and `||` to save even more on if/else verbosity.
|
||||
* Nested ternary operator `?:` to save on `if`/`else` verbosity.
|
||||
* Short circuiting `&&` and `||` to save even more on `if`/`else` verbosity.
|
||||
* Subtraction instead of an equality operator in `*t - 42`.
|
||||
* ASCII codes for `*` and `?`.
|
||||
* Careful use of blanks even though this year's rules have extended
|
||||
that resource limit.
|
||||
* The source is a complete preprocessed C program. Because it communicates
|
||||
with the world out there by means of argv and the exit status, there
|
||||
is no need for stdio bloat. An asm guru could surely squeeze this
|
||||
with the world out there by means of `argv` and the exit status, there
|
||||
is no need for `stdio.h` bloat. An asm guru could surely squeeze this
|
||||
program in less than a screenful.
|
||||
* `indent(1)` is probably not too helpful.
|
||||
|
||||
@@ -101,7 +99,7 @@ backtracking. I could tell you how it works but then I would have to
|
||||
inputs, it will be quite helpful and instructive. Handling of `?` is
|
||||
straightforward; for `*` start out with `*foo` and `foo*` against `foo`.
|
||||
How does it deal with sequences of adjacent `*`? How could this be
|
||||
improved? If all else fails, recode the `?:` operators with if/else and
|
||||
improved? If all else fails, recode the `?:` operators with `if`/`else` and
|
||||
try again. For extra credit implement character classes like `[a-z]`.
|
||||
|
||||
|
||||
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# try.sh - demonstrate IOCCC winner 2001/schweikh
|
||||
#
|
||||
|
||||
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||
# this way allows us to have the user specify a different compiler in an easy
|
||||
# way.
|
||||
if [[ -z "$CC" ]]; then
|
||||
CC="cc"
|
||||
fi
|
||||
|
||||
make CC="$CC" all >/dev/null || exit 1
|
||||
|
||||
# clear screen after compilation so that only the entry is shown
|
||||
clear
|
||||
|
||||
echo "$ ./schweikh foo 'f??'; echo \$?" 1>&2
|
||||
./schweikh foo 'f??'; echo $?
|
||||
|
||||
echo "$ ./schweikh 'best short program' '??st*o**p?*'; echo \$?" 1>&2
|
||||
./schweikh 'best short program' '??st*o**p?*'; echo $?
|
||||
|
||||
echo "$ ./schweikh bar 'f??'; echo \$?" 1>&2
|
||||
./schweikh bar 'f??'; echo $?
|
||||
+14
-4
@@ -145,10 +145,6 @@ westley2: westley2.c
|
||||
westley3: westley3.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||
|
||||
${PROG}.sort: ${PROG}.sort.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||
|
||||
|
||||
# alternative executable
|
||||
#
|
||||
alt: data ${ALT_TARGET}
|
||||
@@ -157,6 +153,20 @@ alt: data ${ALT_TARGET}
|
||||
${PROG}.alt: ${PROG}.alt.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||
|
||||
${PROG}.sort.c: ${PROG}
|
||||
${SORT} -b ${PROG}.c > $@
|
||||
|
||||
${PROG}.sort: ${PROG}.sort.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||
|
||||
${PROG}.punch.c: ${PROG}
|
||||
${SORT} ${PROG}.c > $@
|
||||
|
||||
${PROG}.punch: ${PROG}.punch.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||
|
||||
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
|
||||
+56
-29
@@ -4,19 +4,37 @@
|
||||
make
|
||||
```
|
||||
|
||||
There are two additional programs based on the author's remarks and the original
|
||||
version, provided as alternate code as it might be less portable. See [sorted
|
||||
code](#sorted-code), [punch card code](#punch-card-code) and [alternate
|
||||
code](#alternate-code) below.
|
||||
|
||||
|
||||
### Bugs and (Mis)features:
|
||||
|
||||
The current status of this entry is:
|
||||
|
||||
```
|
||||
STATUS: uses gets() - change to fgets() if possible
|
||||
STATUS: missing files - please provide them
|
||||
```
|
||||
|
||||
For more detailed information see [2001 westley in bugs.md](/bugs.md#2001-westley).
|
||||
|
||||
|
||||
|
||||
|
||||
## To use:
|
||||
|
||||
```sh
|
||||
./westley
|
||||
./westley 2>/dev/null
|
||||
# enter some input, terminate with EOF
|
||||
|
||||
echo foo | ./westley
|
||||
echo foo | ./westley 2>/dev/null
|
||||
|
||||
./westley < westley.c
|
||||
./westley < westley.c 2>/dev/null
|
||||
```
|
||||
|
||||
|
||||
### Try:
|
||||
|
||||
```sh
|
||||
@@ -24,40 +42,49 @@ echo foo | ./westley
|
||||
```
|
||||
|
||||
|
||||
## Alternate code:
|
||||
## Sorted code:
|
||||
|
||||
An alternate version of this entry, [westley.alt.c](westley.alt.c), is provided.
|
||||
This alternate code might be less portable.
|
||||
The author stated that one can sort (ignoring leading blanks i.e. `sort -b`) the
|
||||
code by line and it will always sort the order of the input.
|
||||
|
||||
To compile this alternate version:
|
||||
This is compiled by default; use `westley.sort` as you would `westley` above.
|
||||
|
||||
```sh
|
||||
make alt
|
||||
```
|
||||
|
||||
Use `westley.alt` as you would `westley` above.
|
||||
|
||||
### 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:
|
||||
## 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. The
|
||||
[westley.punch.c](westley.punch.c) code is specifically so that Westley can punch
|
||||
everyone in the face! :-) This is also compiled by default.
|
||||
|
||||
To use, try:
|
||||
|
||||
### Punch card try:
|
||||
|
||||
```sh
|
||||
echo 'Brian Westley does it again!' | ./westley.punch 2>/dev/null
|
||||
```
|
||||
|
||||
|
||||
## Alternate code:
|
||||
|
||||
An alternate version of this entry, [westley.alt.c](westley.alt.c), is provided.
|
||||
This alternate code might be less portable.
|
||||
|
||||
|
||||
### Alternate build:
|
||||
|
||||
|
||||
```sh
|
||||
make alt
|
||||
```
|
||||
|
||||
|
||||
### Alternate use:
|
||||
|
||||
Use `westley.alt` as you would `westley` above.
|
||||
|
||||
|
||||
|
||||
## Judges' remarks:
|
||||
|
||||
Try copying the source to a new file and changing around the
|
||||
@@ -66,11 +93,11 @@ 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-independent code
|
||||
to a new level! :-)
|
||||
This assortment of obfuscated lines takes [position-independent
|
||||
code](https://en.wikipedia.org/wiki/Position-independent_code) to a new level! :-)
|
||||
|
||||
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``
|
||||
blank lines) there are `28!` or `304,888,344,611,713,860,501,504,000,000`
|
||||
versions of the program, all valid C!
|
||||
|
||||
|
||||
@@ -116,7 +143,7 @@ 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,
|
||||
you can use the same call to test() repeatedly in
|
||||
you can use the same call to `test()` repeatedly in
|
||||
different lines to return different values:
|
||||
|
||||
```c
|
||||
@@ -184,7 +211,7 @@ 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`
|
||||
that the `time_t` ptr param to `time(3)` 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
|
||||
@@ -201,9 +228,9 @@ comment), there are technically `28!` different programs, or
|
||||
all legal C.
|
||||
|
||||
```
|
||||
\* except in Florida voting machines
|
||||
* except in Florida voting machines
|
||||
|
||||
\*\* all cards must be face down, nine-edge first, of course.
|
||||
** all cards must be face down, nine-edge first, of course.
|
||||
```
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ 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"
|
||||
echo "printf \"1\n4\n5\" | ./westley 2>/dev/null"
|
||||
printf "1\n4\n5" | ./westley 2>/dev/null
|
||||
|
||||
echo
|
||||
|
||||
@@ -302,7 +302,7 @@ NOTE: this does NOT apply to entries under the INABIAF status (though they're
|
||||
not mutually exclusive in some cases).
|
||||
|
||||
|
||||
## STATUS: uses gets() - change to fgets() if possible (in some cases getline() works)
|
||||
## STATUS: uses gets() - change to fgets() if possible
|
||||
|
||||
NOTE: we're still locating entries and working on fixes with this status so we're not yet
|
||||
ready for help. We will remove this when we are.
|
||||
@@ -348,6 +348,9 @@ _NOTE_: this status is _NOT necessarily mutually exclusive_ with the _INABIAF_
|
||||
during compiling, linking and/or runtime, sometimes causing confusing output (as
|
||||
noted above).
|
||||
|
||||
Sometimes `getline(3)` will work but note that this function also stores the
|
||||
newline just like `fgets(3)`.
|
||||
|
||||
|
||||
## STATUS: missing file(s) - please provide them
|
||||
|
||||
@@ -1426,8 +1429,6 @@ to /dev/null (`2>/dev/null`).
|
||||
|
||||
## 1996 jonth
|
||||
|
||||
### STATUS: INABIAF - please **DO NOT** fix
|
||||
|
||||
### STATUS: INABIAF - please **DO NOT** fix
|
||||
### Source code: [1996/jonth/jonth.c](1996/jonth/jonth.c)
|
||||
### Information: [1996/jonth/README.md](1996/jonth/README.md)
|
||||
@@ -1926,7 +1927,7 @@ Although it is independent of endianness both systems need the same character
|
||||
set. In other words both have to be ASCII or EBCDIC - not one of each.
|
||||
|
||||
|
||||
## 2001 ollinger
|
||||
## 2001 schweikh
|
||||
|
||||
|
||||
### STATUS: INABIAF - please **DO NOT** fix
|
||||
@@ -1939,6 +1940,23 @@ details and a workaround.
|
||||
There's also no way to escape meta characters.
|
||||
|
||||
|
||||
## 2001 westley
|
||||
|
||||
|
||||
### STATUS: uses gets() - change to fgets() if possible
|
||||
### Source code: [2001/westley/westley.c](2001/westley/westley.c)
|
||||
### Information: [2001/westley/README.md](2001/westley/README.md)
|
||||
|
||||
This function uses `gets(3)` but it would be ideal if it used `fgets(3)`. This
|
||||
one is rather complicated and will be looked at later but you are welcome to try
|
||||
and fix this if you wish.
|
||||
|
||||
### STATUS: missing files - please provide them
|
||||
|
||||
The author referred to a file `card.gif` but this file is missing. Do you have
|
||||
it? Please provide it!
|
||||
|
||||
|
||||
# 2002
|
||||
|
||||
There was no IOCCC in 2002.
|
||||
|
||||
+12
-3
@@ -2517,7 +2517,15 @@ sound devices in macOS).
|
||||
## [2001/ctk](2001/ctk/ctk.c) ([README.md](2001/ctk/README.md]))
|
||||
|
||||
The ANSI escape codes were no longer valid but Yusuke provided a patch to fix
|
||||
the ANSI escape codes. Cody tested this for macOS and it works fine.
|
||||
the ANSI escape codes. This works with both linux and macOS.
|
||||
|
||||
Cody fixed this so that it should always restore terminal sanity (echo enabled
|
||||
etc.) after exiting even if you don't press 'q', if you crash or if you kill the
|
||||
program prematurely. This was done by adding an explicit call to `e()` at the
|
||||
end of `main()`.
|
||||
|
||||
Cody also added the [alt code](2001/ctk/README.md#alternate-code) that adds
|
||||
vi(m) movement keys.
|
||||
|
||||
|
||||
## [2001/dgbeards](2001/dgbeards/dgbeards.c) ([README.md](2001/dgbeards/README.md]))
|
||||
@@ -2528,8 +2536,7 @@ that the idea of crashing on losing (see the README.md for details on why that
|
||||
might be) too good to get rid of so he kept that in.
|
||||
|
||||
He also points out that there is a way to get the computer to automatically lose
|
||||
very quickly and he also points out that there is a flaw in the alternate
|
||||
version that the author did not note. Do you know what these are?
|
||||
very quickly. Do you know what it is?
|
||||
|
||||
|
||||
## [2001/herrmann1](2001/herrmann1/herrmann1.c) ([README.md](2001/herrmann1/README.md]))
|
||||
@@ -2587,6 +2594,8 @@ Cody fixed this to not crash if not enough args as this was not documented by
|
||||
the author. The other problems are documented so were not fixed. See
|
||||
README.md for details.
|
||||
|
||||
Cody also added the [try.sh](2001/schweikh/try.sh) script.
|
||||
|
||||
|
||||
## [2001/westley](2001/westley/westley.c) ([README.md](2001/westley/README.md]))
|
||||
|
||||
|
||||
Reference in new issue
Block a user