Merge pull request #1687 from xexyl/hou2018
This commit is contained in:
22 files changed
+425
-336
No files matched your search
@@ -8,4 +8,5 @@ prog.orig
|
|||||||
shapiro
|
shapiro
|
||||||
shapiro.orig
|
shapiro.orig
|
||||||
shapiro_t1
|
shapiro_t1
|
||||||
|
shapiro_t2
|
||||||
shapiro_t2.c
|
shapiro_t2.c
|
||||||
@@ -39,7 +39,7 @@ include ../../var.mk
|
|||||||
# Common C compiler warnings to silence
|
# Common C compiler warnings to silence
|
||||||
#
|
#
|
||||||
CSILENCE= -Wno-error -Wno-implicit-function-declaration -Wno-shift-op-parentheses \
|
CSILENCE= -Wno-error -Wno-implicit-function-declaration -Wno-shift-op-parentheses \
|
||||||
-Wno-deprecated-non-prototype -Wno-strict-prototypes
|
-Wno-deprecated-non-prototype -Wno-strict-prototypes -Wno-implicit-int
|
||||||
|
|
||||||
# Common C compiler warning flags
|
# Common C compiler warning flags
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ The current status of this entry is:
|
|||||||
|
|
||||||
```
|
```
|
||||||
STATUS: missing file - please provide it
|
STATUS: missing file - please provide it
|
||||||
|
STATUS: INABIAF - please **DO NOT** fix
|
||||||
```
|
```
|
||||||
|
|
||||||
For more detailed information see [1994 shapiro in bugs.md](/bugs.md#1994-shapiro).
|
For more detailed information see [1994 shapiro in bugs.md](/bugs.md#1994-shapiro).
|
||||||
@@ -45,7 +46,7 @@ back to the foreground what happens.
|
|||||||
This entry has many different levels of obfuscation, and yet the
|
This entry has many different levels of obfuscation, and yet the
|
||||||
source file is self documenting. :-)
|
source file is self documenting. :-)
|
||||||
|
|
||||||
From time to time, run ps and look at the new processes.
|
From time to time, run `ps(1)` and look at the new processes.
|
||||||
|
|
||||||
See [shapiro.md](shapiro.md) for more information in the internals of this program.
|
See [shapiro.md](shapiro.md) for more information in the internals of this program.
|
||||||
The file [shapiro.alt.c](shapiro.alt.c) contains a non-obfuscated version of
|
The file [shapiro.alt.c](shapiro.alt.c) contains a non-obfuscated version of
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ them with cool layout!
|
|||||||
For your enjoyment:
|
For your enjoyment:
|
||||||
|
|
||||||
1. Compile [dhyang.c](dhyang.c).
|
1. Compile [dhyang.c](dhyang.c).
|
||||||
2. Run `./dhyang` and pipe output to another `.c` file.
|
2. Run `./dhyang` and redirect output to another `.c` file.
|
||||||
3. Compile that file.
|
3. Compile that file.
|
||||||
4. Repeat steps 2 and 3 until eventually the output cycles.
|
4. Repeat steps 2 and 3 until eventually the output cycles.
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ terminal fonts to as close to square as possible. I hate to do this
|
|||||||
but you know, size...
|
but you know, size...
|
||||||
|
|
||||||
[dhyang.c](dhyang.c) and all its output compiles with gcc if your OS uses ASCII
|
[dhyang.c](dhyang.c) and all its output compiles with gcc if your OS uses ASCII
|
||||||
character set. No file is included and all functions assume default int return
|
character set. No file is included and all functions assume default `int` return
|
||||||
type (a source of compile warnings).
|
type (a source of compile warnings).
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+9
-6
@@ -22,8 +22,9 @@ make saitou >/dev/null
|
|||||||
echo "$ ./saitou > aku.c" 1>&2
|
echo "$ ./saitou > aku.c" 1>&2
|
||||||
./saitou > aku.c
|
./saitou > aku.c
|
||||||
|
|
||||||
echo "$ cat aku.c"
|
read -r -n 1 -p "Press any key to run: cat aku.c (space = next page, q = quit): "
|
||||||
cat aku.c
|
echo 1>&2
|
||||||
|
cat aku.c | less -EXF
|
||||||
|
|
||||||
echo "$ make soku >/dev/null" 1>&2
|
echo "$ make soku >/dev/null" 1>&2
|
||||||
make soku >/dev/null
|
make soku >/dev/null
|
||||||
@@ -31,8 +32,9 @@ make soku >/dev/null
|
|||||||
echo "$ ./soku > soku.c" 1>&2
|
echo "$ ./soku > soku.c" 1>&2
|
||||||
./soku > soku.c
|
./soku > soku.c
|
||||||
|
|
||||||
echo "$ cat soku.c" 1>&2
|
read -r -n 1 -p "Press any key to run: cat soku.c (space = next page, q = quit): "
|
||||||
cat soku.c
|
echo 1>&2
|
||||||
|
cat soku.c | less -EXF
|
||||||
|
|
||||||
echo "$ make zan >/dev/null" 1>&2
|
echo "$ make zan >/dev/null" 1>&2
|
||||||
make zan >/dev/null
|
make zan >/dev/null
|
||||||
@@ -40,8 +42,9 @@ make zan >/dev/null
|
|||||||
echo "$ ./zan > zan.c" 1>&2
|
echo "$ ./zan > zan.c" 1>&2
|
||||||
./zan > zan.c
|
./zan > zan.c
|
||||||
|
|
||||||
echo "$ cat zan.c" 1>&2
|
read -r -n 1 -p "Press any key to run: cat zan.c (space = next page, q = quit): "
|
||||||
cat zan.c
|
echo 1>&2
|
||||||
|
cat zan.c | less -EXF
|
||||||
|
|
||||||
echo "$ make aku >/dev/null" 1>&2
|
echo "$ make aku >/dev/null" 1>&2
|
||||||
make aku >/dev/null
|
make aku >/dev/null
|
||||||
|
|||||||
+46
-29
@@ -4,6 +4,10 @@
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
There is an alternate version that lacks a useful bug fix. See [Alternate
|
||||||
|
code](#alternate-code) and the author's remarks ([remarks section](#remarks))
|
||||||
|
below for more details.
|
||||||
|
|
||||||
|
|
||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
@@ -22,31 +26,38 @@ make
|
|||||||
|
|
||||||
## Alternate code:
|
## Alternate code:
|
||||||
|
|
||||||
An alternate version of this entry, `prog.alt.c`, is provided. As mentioned in
|
An alternate version of this entry, [prog.alt.c](prog.alt.c), is provided. As
|
||||||
the Author's remarks, the alternate version lacks a useful bug fix.
|
mentioned in the author's [remarks](#remarks), the alternate version lacks a
|
||||||
|
useful bug fix.
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate build:
|
||||||
|
|
||||||
To compile this alternate version:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make alt
|
make alt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate use:
|
||||||
|
|
||||||
Use `prog.alt` as you would `prog` above.
|
Use `prog.alt` as you would `prog` above.
|
||||||
|
|
||||||
|
|
||||||
## Judges' remarks:
|
## Judges' remarks:
|
||||||
|
|
||||||
This text was processed by prog. You may get confused.
|
This text was processed by `prog`. You may get confused. We're not really sure:
|
||||||
We're not really sure: prog.c wasn't commented.
|
[prog.c](prog.c) wasn't commented. Who has been thoroughly puzzled by `prog`?
|
||||||
Who has been thoroughly puzzled by prog? Also how obfuscated is prog?
|
Also how obfuscated is `prog`? Having been written in C, how large of a
|
||||||
Having been written in C, how large of a vocabulary has it?
|
vocabulary has it?
|
||||||
|
|
||||||
|
|
||||||
## Author's remarks:
|
## Author's remarks:
|
||||||
|
|
||||||
|
|
||||||
### The Program:
|
### The Program:
|
||||||
|
|
||||||
"The Elements of Style" by prof. William Strunk, Jr. and E. B. White
|
"The Elements of Style" by Prof. William Strunk, Jr. and E. B. White
|
||||||
is well known for its dislike of the passive voice. Direct, vigorous,
|
is well known for its dislike of the passive voice. Direct, vigorous,
|
||||||
active constructions were instead recommended by the authors.
|
active constructions were instead recommended by the authors.
|
||||||
The development of this program has been driven by this tenet.
|
The development of this program has been driven by this tenet.
|
||||||
@@ -69,22 +80,24 @@ constructions are recognized:
|
|||||||
Sentences are never broken by periods that follow abbreviations and
|
Sentences are never broken by periods that follow abbreviations and
|
||||||
initials. Both regular and irregular past participles are properly
|
initials. Both regular and irregular past participles are properly
|
||||||
dealt with. Note that some words are red herrings: even though their
|
dealt with. Note that some words are red herrings: even though their
|
||||||
ending is -ed, they are not past participles.
|
ending is `-ed`, they are not past participles.
|
||||||
|
|
||||||
|
|
||||||
### The Big String:
|
### The Big String:
|
||||||
|
|
||||||
Here is the purpose of every byte inside the `c[]` string:
|
Here is the purpose of every byte inside the `c[]` string:
|
||||||
|
|
||||||
* 0-9: highlighting passive constructions in the output.
|
* `0-9`: highlighting passive constructions in the output.
|
||||||
* 10-50: classifying characters - called by `V(4)`.
|
* `10-50`: classifying characters - called by `V(4)`.
|
||||||
* 52: outputting the newline character.
|
* `52`: outputting the newline character.
|
||||||
* 51-187: tokenizing text and detecting passive constructions - two type A
|
* `51-187`: tokenizing text and detecting passive constructions - two type A
|
||||||
state machines, called by `V(2)` and `V(3)`.
|
state machines, called by `V(2)` and `V(3)`.
|
||||||
* 186-2786: determining word categories (past participles, present simple and
|
* `186-2786`: determining word categories (past participles, present simple and
|
||||||
past simple forms of "to be", other forms of "to be", adverbs, wh-words, and
|
past simple forms of "to be", other forms of "to be", adverbs, wh-words, and
|
||||||
other words) and recognizing abbreviations - two type B state machines, called
|
other words) and recognizing abbreviations - two type B state machines, called
|
||||||
by `V(808)` and `V(205)`.
|
by `V(808)` and `V(205)`.
|
||||||
|
|
||||||
|
|
||||||
### The State Machines:
|
### The State Machines:
|
||||||
|
|
||||||
I heard you don't like state machines so I put a state machine in your
|
I heard you don't like state machines so I put a state machine in your
|
||||||
@@ -94,6 +107,7 @@ Both types of state machines in the program are Mealy machines: we can
|
|||||||
think of their transitions as triples (`transition_label`,
|
think of their transitions as triples (`transition_label`,
|
||||||
`next_state`, `output`).
|
`next_state`, `output`).
|
||||||
|
|
||||||
|
|
||||||
### Type A:
|
### Type A:
|
||||||
|
|
||||||
A state of type A state machine consists of eight transitions whose
|
A state of type A state machine consists of eight transitions whose
|
||||||
@@ -155,11 +169,12 @@ And here are sample steps of scanning tokens with classes `to_be`,
|
|||||||
* `state` = 22, `transition_label` = 0 (`adverb`), `output` = `ignore`
|
* `state` = 22, `transition_label` = 0 (`adverb`), `output` = `ignore`
|
||||||
* `state` = 22, `transition_label` = 3 (`past_participle`), `output` = `passive_construction_end`
|
* `state` = 22, `transition_label` = 3 (`past_participle`), `output` = `passive_construction_end`
|
||||||
|
|
||||||
|
|
||||||
### Type B:
|
### Type B:
|
||||||
|
|
||||||
Type B state machines are built by a variant of the algorithm described
|
Type B state machines are built by a variant of the algorithm described
|
||||||
in the paper
|
in the paper
|
||||||
[How to squeeze a lexicon](http://sun.aei.polsl.pl/~mciura/publikacje/lexicon.pdf).
|
[How to squeeze a lexicon (PDF)](lexicon.pdf).
|
||||||
Their states are represented as interlaced sparse arrays of transitions.
|
Their states are represented as interlaced sparse arrays of transitions.
|
||||||
|
|
||||||
The `transition_label` is one of:
|
The `transition_label` is one of:
|
||||||
@@ -203,6 +218,7 @@ A type B state machine starts in a given `state` with `output`
|
|||||||
set to `ignore`. It scans a word backwards, converting character by
|
set to `ignore`. It scans a word backwards, converting character by
|
||||||
character to `transition_label`. When it meets `word_start`, it
|
character to `transition_label`. When it meets `word_start`, it
|
||||||
returns, leaving the most recently stored `output` in `v`.
|
returns, leaving the most recently stored `output` in `v`.
|
||||||
|
|
||||||
It also returns when
|
It also returns when
|
||||||
`c[186 + (state + transition_label)] != (unsigned char)(2 + transition_label + 28 * output)`,
|
`c[186 + (state + transition_label)] != (unsigned char)(2 + transition_label + 28 * output)`,
|
||||||
i.e. when the `transition_label` in the byte mismatches the
|
i.e. when the `transition_label` in the byte mismatches the
|
||||||
@@ -215,33 +231,34 @@ class is set up so that it never returns `ignore`.
|
|||||||
|
|
||||||
Below are sample steps of scanning the word "chiefly".
|
Below are sample steps of scanning the word "chiefly".
|
||||||
|
|
||||||
* `state` = 623, `transition_label` = 26 ('y'), `output` = `other`
|
* `state` = 623, `transition_label` = 26 (`'y'`), `output` = `other`
|
||||||
* `state` = 602, `transition_label` = 13 ('l'), `output` = `adverb`
|
* `state` = 602, `transition_label` = 13 (`'l'`), `output` = `adverb`
|
||||||
* `state` = 594, `transition_label` = 7 ('f'), `output` = `other`
|
* `state` = 594, `transition_label` = 7 (`'f'`), `output` = `other`
|
||||||
* `state` = 549, `transition_label` = 6 ('e'), `output` = `ignore`
|
* `state` = 549, `transition_label` = 6 (`'e'`), `output` = `ignore`
|
||||||
* `state` = 543, `transition_label` = 10 ('i'), `output` = `adverb`
|
* `state` = 543, `transition_label` = 10 (`'i'`), `output` = `adverb`
|
||||||
* `state` = 0, `transition_label` = 9 ('h') mismatches the value stored
|
* `state` = 0, `transition_label` = 9 (`'h'`) mismatches the value stored
|
||||||
in the byte. Return `adverb`.
|
in the byte. Return `adverb`.
|
||||||
|
|
||||||
And here are sample steps of scanning the string "i.e.":
|
And here are sample steps of scanning the string "i.e.":
|
||||||
|
|
||||||
* `state` = 19, `transition_label` = 1 ('.'), `output` = `ignore`
|
* `state` = 19, `transition_label` = 1 (`'.'`), `output` = `ignore`
|
||||||
* `state` = 24, `transition_label` = 6 ('e'), `output` = `ignore`
|
* `state` = 24, `transition_label` = 6 (`'e'`), `output` = `ignore`
|
||||||
* `state` = 3, `transition_label` = 1 ('.'), `output` = `ignore`
|
* `state` = 3, `transition_label` = 1 (`'.'`), `output` = `ignore`
|
||||||
* `state` = 2, `transition_label` = 10 ('i'), `output` = `ignore`
|
* `state` = 2, `transition_label` = 10 (`'i'`), `output` = `ignore`
|
||||||
* `state` = 1, `transition_label` = 0 ('\0'), `output` = `abbreviation`.
|
* `state` = 1, `transition_label` = 0 (`'\0'`), `output` = `abbreviation`.
|
||||||
Return `abbreviation`.
|
Return `abbreviation`.
|
||||||
|
|
||||||
|
|
||||||
### Remarks:
|
### Remarks:
|
||||||
|
|
||||||
The judges found a bug in the handling of contractions: `prog.alt.c`
|
The judges found a bug in the handling of contractions: [prog.alt.c](prog.alt.c)
|
||||||
outputs "foo wasn'**[t bazzed]**". I fixed the bug in `prog.c`, making
|
outputs "foo wasn'**[t bazzed]**". I fixed the bug in [prog.c](prog.c), making
|
||||||
it output "foo **[wasn't bazzed]**" instead, and took the liberty to merge
|
it output "foo **[wasn't bazzed]**" instead, and took the liberty to merge
|
||||||
one statement into a `for` loop inside its `main()` function.
|
one statement into a `for` loop inside its `main()` function.
|
||||||
|
|
||||||
The program uses a 9,437,187-byte buffer so it probably will not run
|
The program uses a 9,437,187-byte buffer so it probably will not run
|
||||||
on 16-bit and smaller machines without changing the size of array `C[]`
|
on 16-bit and smaller machines without changing the size of array `C[]`
|
||||||
and the expression `9<<20` inside the call to `read()`.
|
and the expression `9<<20` inside the call to `read(2)`.
|
||||||
|
|
||||||
I have tested it on:
|
I have tested it on:
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Executable
+27
@@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2018/ciura
|
||||||
|
#
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./prog < Makefile: "
|
||||||
|
echo 1>&2
|
||||||
|
./prog < Makefile
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./prog < README.md: "
|
||||||
|
echo 1>&2
|
||||||
|
./prog < README.md
|
||||||
|
|
||||||
|
exit 0
|
||||||
+1
-14
@@ -24,20 +24,7 @@ Makefile The Makefile that simplifies compilation as well as
|
|||||||
itself [1].
|
itself [1].
|
||||||
|
|
||||||
|
|
||||||
weasel.man The local version of the man page; that is if it's
|
weasel.1 The man page for weasel.
|
||||||
not installed. You can still use 'man' on the
|
|
||||||
'weasel.1' file but 'weasel.man' references
|
|
||||||
different file paths from 'weasel.1'.
|
|
||||||
|
|
||||||
|
|
||||||
weasel.1 The system wide version of the man page for when
|
|
||||||
(if) it's installed [2]. Note that the suggested
|
|
||||||
invocation 'man -l ./weasel.man' can be replaced
|
|
||||||
with 'man -l ./weasel.1' too but if the weasel
|
|
||||||
package is installed 'man weasel.1' (note the
|
|
||||||
missing '-l ./') would read the from the system
|
|
||||||
man page.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
README.md The source of the index.html file [3].
|
README.md The source of the index.html file [3].
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ PROG= prog
|
|||||||
#
|
#
|
||||||
OBJ= ${PROG}.o
|
OBJ= ${PROG}.o
|
||||||
CSRC= ${PROG}.o
|
CSRC= ${PROG}.o
|
||||||
DATA= FILES hint.css rpm.md test-strings.txt weasel.1 weasel.man weasel.spec
|
DATA= FILES hint.css rpm.md test-strings.txt weasel.1 weasel.spec
|
||||||
TARGET= ${PROG} weasel
|
TARGET= ${PROG} weasel
|
||||||
#
|
#
|
||||||
ALT_OBJ= ${PROG}.alt
|
ALT_OBJ= ${PROG}.alt
|
||||||
|
|||||||
+28
-10
@@ -4,6 +4,9 @@
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The author provided an alternate version which has a simpler keyboard for the
|
||||||
|
monkey Eric. See [Alternate code](#alternate-code) below.
|
||||||
|
|
||||||
|
|
||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
@@ -15,20 +18,35 @@ make
|
|||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./weasel words
|
./try.sh
|
||||||
./weasel -mq words
|
|
||||||
./weasel -q -r8 'EVOLUTION IS A PROVEN FACT'
|
|
||||||
./weasel -m 'INTELLIGENT DESIGN'
|
|
||||||
|
|
||||||
make test
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Alternate code:
|
## Alternate code:
|
||||||
|
|
||||||
The author provided an alternate version which has a simpler keyboard for the
|
This version has a simpler keyboard (fewer characters). The author wrote more
|
||||||
monkey Eric. See his comments under the 'keyboards' section, briefly referred to
|
about this under the [keyboards](#keyboards) section, briefly referred to in the
|
||||||
in the 'what it is' section.
|
[what it is](#what) section.
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate build:
|
||||||
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make alt
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate use:
|
||||||
|
|
||||||
|
Use `weasel.alt` as you would `weasel` above.
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate try:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./try.alt.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Judges' remarks:
|
## Judges' remarks:
|
||||||
@@ -50,7 +68,7 @@ while using more Cenozoic minded code migration, read rpm.md.
|
|||||||
If you find yourself in an evolutionary dead end, try:
|
If you find yourself in an evolutionary dead end, try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
man ./weasel.man
|
man ./weasel.1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Make sure the program has been compiled
|
# Make sure the program has been compiled
|
||||||
make clobber all 1> /dev/null|| exit 1
|
make everything 1> /dev/null|| exit 1
|
||||||
|
|
||||||
while read -r f; do
|
while read -r f; do
|
||||||
./weasel "$@" "${f}" # full line because of quotes
|
./weasel "$@" "${f}" # full line because of quotes
|
||||||
|
|||||||
Executable
+52
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.alt.sh - demonstrate IOCCC winner 2018/ferguson alt code
|
||||||
|
#
|
||||||
|
|
||||||
|
# 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" alt >/dev/null || exit 1
|
||||||
|
|
||||||
|
# clear screen after compilation so that only the entry is shown
|
||||||
|
clear
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./weasel.alt words (space = next page, q = quit): "
|
||||||
|
echo 1>&2
|
||||||
|
time ./weasel.alt words | less -EXF
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to see how long it'll take Eric the monkey to type his name: "
|
||||||
|
echo 1>&2
|
||||||
|
time ./weasel.alt -mq Eric
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: make test: "
|
||||||
|
echo 1>&2
|
||||||
|
make test
|
||||||
|
|
||||||
|
read -r -p "Do you wish to try and prove 'intelligent design' (Y/N)? "
|
||||||
|
if [[ "$REPLY" == "Y" || "$REPLY" == "y" ]]; then
|
||||||
|
echo "$ ./weasel.alt -m 'INTELLIGENT DESIGN'" 1>&2
|
||||||
|
echo "Press any key to continue. Send ctrl-c when convinced that intelligent" 1>&2
|
||||||
|
read -r -n 1 -p "design is not real or you're tired of waiting: "
|
||||||
|
echo 1>&2
|
||||||
|
time ./weasel.alt -m 'INTELLIGENT DESIGN'
|
||||||
|
echo 1>&2
|
||||||
|
else
|
||||||
|
echo "$ ./weasel.alt -q -r8 'EVOLUTION IS A PROVEN FACT'" 1>&2
|
||||||
|
time ./weasel.alt -q -r8 'EVOLUTION IS A PROVEN FACT'
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -r -n 1 -p "Do you want to see how long it might take the monkey Eric to type 'words'? (Y/N)? "
|
||||||
|
if [[ "$REPLY" == "Y" || "$REPLY" == "y" ]]; then
|
||||||
|
echo 1>&2
|
||||||
|
echo "Will not display until Eric succeeds or too many generations. Hit ctrl-c" 1>&2
|
||||||
|
echo "to stop him early." 1>&2
|
||||||
|
read -r -n 1 -p "Press any key to continue: "
|
||||||
|
echo 1>&2
|
||||||
|
time ./weasel.alt -mq words
|
||||||
|
fi
|
||||||
Executable
+52
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2018/ferguson
|
||||||
|
#
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./weasel words (space = next page, q = quit): "
|
||||||
|
echo 1>&2
|
||||||
|
time ./weasel words | less -EXF
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to see how long it'll take Eric the monkey to type his name: "
|
||||||
|
echo 1>&2
|
||||||
|
time ./weasel -mq Eric
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: make test: "
|
||||||
|
echo 1>&2
|
||||||
|
make test
|
||||||
|
|
||||||
|
read -r -p "Do you wish to try and prove 'intelligent design' (Y/N)? "
|
||||||
|
if [[ "$REPLY" == "Y" || "$REPLY" == "y" ]]; then
|
||||||
|
echo "$ ./weasel -m 'INTELLIGENT DESIGN'" 1>&2
|
||||||
|
echo "Press any key to continue. Send ctrl-c when convinced that intelligent" 1>&2
|
||||||
|
read -r -n 1 -p "design is not real or you're tired of waiting: "
|
||||||
|
echo 1>&2
|
||||||
|
time ./weasel -m 'INTELLIGENT DESIGN'
|
||||||
|
echo 1>&2
|
||||||
|
else
|
||||||
|
echo "$ ./weasel -q -r8 'EVOLUTION IS A PROVEN FACT'" 1>&2
|
||||||
|
time ./weasel -q -r8 'EVOLUTION IS A PROVEN FACT'
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -r -n 1 -p "Do you want to see how long it might take the monkey Eric to type 'words'? (Y/N)? "
|
||||||
|
if [[ "$REPLY" == "Y" || "$REPLY" == "y" ]]; then
|
||||||
|
echo 1>&2
|
||||||
|
echo "Will not display until Eric succeeds or too many generations. Hit ctrl-c" 1>&2
|
||||||
|
echo "to stop him early." 1>&2
|
||||||
|
read -r -n 1 -p "Press any key to continue: "
|
||||||
|
echo 1>&2
|
||||||
|
time ./weasel -mq words
|
||||||
|
fi
|
||||||
@@ -135,40 +135,6 @@ was disabled as above). Observe that here the \fB-r5-q\fP doesn't prevent the
|
|||||||
quiet output from being enabled; on the other hand the options
|
quiet output from being enabled; on the other hand the options
|
||||||
\fB-r5- -q -- -r10\fP would!
|
\fB-r5- -q -- -r10\fP would!
|
||||||
.RE
|
.RE
|
||||||
.SH FILES
|
|
||||||
\fI/usr/src/weasel/weasel.c\fP
|
|
||||||
.RS
|
|
||||||
The source code to the \fBweasel\fP program.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fI/usr/src/weasel/weasel.alt.c\fP
|
|
||||||
.RS
|
|
||||||
The source code to the \fBweasel.alt\fP program.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fI/usr/src/weasel/Makefile\fP
|
|
||||||
.RS
|
|
||||||
The Makefile to compile the source code should you wish to compile the
|
|
||||||
source code files.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fI/usr/src/weasel/test.sh\fP
|
|
||||||
.RS
|
|
||||||
A test script that demonstrates the weasel program (this script is used
|
|
||||||
by \fBmake test\fP) by reading in strings, one at a time, and invoking
|
|
||||||
the program with that string as the target chromosome. See the
|
|
||||||
\fIREADME.md\fP or \fIhint.html\fP for more details on using this script.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fI/usr/src/weasel/test-strings.txt\fP
|
|
||||||
.RS
|
|
||||||
The data file the \fItest.sh\fP script reads strings from.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fI/usr/share/doc/weasel/weasel.html\fP, \fI/usr/share/doc/weasel/weasel.markdown\fP
|
|
||||||
.RS
|
|
||||||
More detailed documentation.
|
|
||||||
.RE
|
|
||||||
.SH HINTS
|
.SH HINTS
|
||||||
The IOCCC judges in 2018 asked the following in the guidelines:
|
The IOCCC judges in 2018 asked the following in the guidelines:
|
||||||
.RS
|
.RS
|
||||||
|
|||||||
@@ -1,192 +0,0 @@
|
|||||||
.TH weasel 1 "15 February 2023" "weasel" "IOCCC 2018"
|
|
||||||
.SH NAME
|
|
||||||
weasel \- The IOCCC 2018 Implementation of Richard Dawkins's Weasel program
|
|
||||||
.SH SYNOPSIS
|
|
||||||
\fBweasel\fP [\fI\-r<rate>\fP] [\fI\-m\fP] [\fI\-q\fP] [<\fIchromosomal string\fP>]
|
|
||||||
.PP
|
|
||||||
\fBweasel.alt\fP [\fI\-r<rate>\fP] [\fI\-m\fP] [\fI\-q\fP] [<\fIchromosomal string\fP>]
|
|
||||||
.SH DESCRIPTION
|
|
||||||
\fBweasel\fP is an obfuscated implementation of Richard Dawkins' \fIWeasel program\fP.
|
|
||||||
According to Wikipedia in chapter three of his book \fIThe Blind Watchmaker\fP Dawkins wrote:
|
|
||||||
.PP
|
|
||||||
.RS
|
|
||||||
I don't know who it was first pointed out that, given enough time,
|
|
||||||
a monkey bashing away at random on a typewriter could produce all
|
|
||||||
the works of Shakespeare. The operative phrase is, of course, given
|
|
||||||
enough time. Let us limit the task facing our monkey somewhat.
|
|
||||||
Suppose that he has to produce, not the complete works of Shakespeare
|
|
||||||
but just the short sentence 'Methinks it is like a weasel', and we
|
|
||||||
shall make it relatively easy by giving him a typewriter with a
|
|
||||||
restricted keyboard, one with just the 26 (capital) letters, and
|
|
||||||
a space bar. How long will he take to write this one little sentence?
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
He refers to the \fIInfinite Monkey Theorem\fP in particular and as he
|
|
||||||
points out it is \fBgiven enough time.\fP The weasel program uses a \fIgenetic
|
|
||||||
algorithm (GA)\fP to intelligently come to a conclusion but this implementation
|
|
||||||
has several additions: \fBtwo Easter eggs,\fP a \fBquiet output mode,\fP
|
|
||||||
an \fBoption to change the mutation rate\fP as well as the ability to
|
|
||||||
\fBspecify the chromosomal string.\fP
|
|
||||||
Furthermore the keyboard isn't as limited as Dawkins's implementation.
|
|
||||||
The \fBweasel.alt\fP keyboard is a more limited keyboard but not
|
|
||||||
as limited as Dawkins's Weasel program keyboard.
|
|
||||||
.SH OPTIONS
|
|
||||||
.PP
|
|
||||||
\fB\-r\fP\fI<rate>\fP
|
|
||||||
This sets the mutation rate to \fI<rate>\fP; valid range is 1 through 100.
|
|
||||||
Anything outside this range will disable the genetic algorithm and simulate
|
|
||||||
a monkey in front of a typewriter.
|
|
||||||
If a valid mutation rate is set after this then the monkey typewriter mode
|
|
||||||
will be disabled but if monkey mode has been explicitly requested by the
|
|
||||||
\fB\-m\fP option the mutation rate is ignored.
|
|
||||||
Note that there cannot be a space between the \fB\-r\fP and \fI<rate>\fP.
|
|
||||||
The default is 1; valid range is >= 1 && <= 100.
|
|
||||||
.PP
|
|
||||||
\fB\-m\fP
|
|
||||||
Set monkey mode. This disables the genetic algorithm and is disables the
|
|
||||||
mutation rate entirely; instead it will pseudo-randomly select a character
|
|
||||||
from the keyboard in every offspring for every generation and selection
|
|
||||||
will not take place: parents are simply the first two offspring
|
|
||||||
regardless of their fitness score. Once this is enabled you
|
|
||||||
cannot disable it: be wary of the typing monkeys!
|
|
||||||
.PP
|
|
||||||
\fB\-q\fP
|
|
||||||
Quiet output.
|
|
||||||
Only display settings like mutation rate, quiet output,
|
|
||||||
target string and the final answer - if it comes to one.
|
|
||||||
Just like monkey mode you cannot disable this once it's been enabled.
|
|
||||||
.PP
|
|
||||||
\fB--\fP
|
|
||||||
Disable parsing of additional options (but not target strings); see
|
|
||||||
.B EXAMPLES
|
|
||||||
for a subtle point.
|
|
||||||
.SH EXIT STATUS
|
|
||||||
On error of any kind (including reaching the maximum number of attempts)
|
|
||||||
return 1; otherwise return 0.
|
|
||||||
.SH BUGS
|
|
||||||
Bugs? What's this? :) Any bugs are actually insolent monkeys tampering
|
|
||||||
with the program! But if you insist I do include errata on my website.
|
|
||||||
.SH EXAMPLES
|
|
||||||
.PP
|
|
||||||
\fBweasel\fP
|
|
||||||
.PP
|
|
||||||
.NF
|
|
||||||
Using the GA with the default mutation rate of 1 and output mode (verbose)
|
|
||||||
look for the default string in Hawkins's Weasel program; note that in
|
|
||||||
all cases the string to be found is capitalised.
|
|
||||||
.FI
|
|
||||||
.PP
|
|
||||||
\fBweasel \-qr5
|
|
||||||
weasel \-q \-r5\fP
|
|
||||||
.NF
|
|
||||||
.PP
|
|
||||||
Enables quiet output and sets a mutation rate of 5.
|
|
||||||
.PP
|
|
||||||
.FI
|
|
||||||
\fBweasel \-rqr10\fP
|
|
||||||
.NF
|
|
||||||
.PP
|
|
||||||
First sets an invalid mutation rate, then enables quiet output and
|
|
||||||
finally sets (a valid) mutation rate of 10.
|
|
||||||
.FI
|
|
||||||
.PP
|
|
||||||
.NF
|
|
||||||
\fBweasel \-m 'I AM A MONKEY TYPING'\fP
|
|
||||||
.PP
|
|
||||||
.FI
|
|
||||||
Simulate a monkey typing at the typewriter trying to type out the
|
|
||||||
string \fBI AM A MONKEY TYPING\fP without quotes. Note that this will
|
|
||||||
take some time almost assuredly and you might fall asleep before
|
|
||||||
the monkey succeeds. Here you would see all the attempts because
|
|
||||||
quiet output was not requested.
|
|
||||||
.PP
|
|
||||||
\fBweasel I AM NOT A MONKEY\fP
|
|
||||||
.PP
|
|
||||||
.NF
|
|
||||||
Using the GA find the final string specified (this always happens);
|
|
||||||
because the string wasn't quoted the program will have seen each word
|
|
||||||
as a separate argument and thus it would search for \fBMONKEY\fP.
|
|
||||||
.FI
|
|
||||||
.PP
|
|
||||||
\fBweasel '"WEASEL"'\fP
|
|
||||||
.PP
|
|
||||||
.NF
|
|
||||||
Search for the string \fB"WEASEL"\fP including double quotes ("s).
|
|
||||||
.FI
|
|
||||||
.PP
|
|
||||||
\fBweasel "'WEASEL'"\fP
|
|
||||||
.PP
|
|
||||||
.NF
|
|
||||||
Search for the string \fB'WEASEL'\fP including the single quotes ('s).
|
|
||||||
.FI
|
|
||||||
.PP
|
|
||||||
\fBweasel \-q \-r5 \-\- \-r10\fP
|
|
||||||
.PP
|
|
||||||
.NF
|
|
||||||
Enable quiet output, set mutation rate to 5, disable further option parsing
|
|
||||||
and set target string to \fB-r10\fP (literally because option parsing was disabled).
|
|
||||||
.FI
|
|
||||||
.PP
|
|
||||||
\fBweasel \-r5\-q \-\- \-r10\fP
|
|
||||||
.PP
|
|
||||||
Set mutation rate to 5, enable quiet output, disable further parsing of
|
|
||||||
options and set target string to \fB-r10\fP (literally - because option parsing
|
|
||||||
was disabled as above). Observe that here the \fB-r5-q\fP doesn't prevent the
|
|
||||||
quiet output from being enabled; on the other hand the options
|
|
||||||
\fB-r5- -q -- -r10\fP would!
|
|
||||||
.RE
|
|
||||||
.SH FILES
|
|
||||||
\fIprog.c\fP
|
|
||||||
.RS
|
|
||||||
The source code to the \fBweasel\fP program.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fIprog.alt.c\fP
|
|
||||||
.RS
|
|
||||||
The source code to the \fBweasel.alt\fP program.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fIMakefile\fP
|
|
||||||
.RS
|
|
||||||
The Makefile to compile the source code should you wish to compile the
|
|
||||||
source code files.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fItest.sh\fP
|
|
||||||
.RS
|
|
||||||
A test script that demonstrates the weasel program (this script is used
|
|
||||||
by \fBmake test\fP) by reading in strings, one at a time, and invoking
|
|
||||||
the program with that string as the target chromosome. See the
|
|
||||||
\fIREADME.md\fP or \fIhint.html\fP for more details on using this script.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fItest-strings.txt\fP
|
|
||||||
.RS
|
|
||||||
The data file the \fItest.sh\fP script reads strings from.
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
\fIhint.html\fP, \fIREADME.md\fP
|
|
||||||
.RS
|
|
||||||
More detailed documentation.
|
|
||||||
.RE
|
|
||||||
.SH HINTS
|
|
||||||
The IOCCC judges in 2018 asked the following in the guidelines:
|
|
||||||
.RS
|
|
||||||
.PP
|
|
||||||
\fBBTW: What is so special about 2305567963945518424753102147331756070? You tell us!\fP
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
It is the primorial prime of 97; but can you find a way to get the program
|
|
||||||
to by default search for this number instead? You might need the source code to
|
|
||||||
find it!
|
|
||||||
.SH SEE ALSO
|
|
||||||
.NF
|
|
||||||
<\fBhttps://ioccc.xexyl.net/2018/weasel\fP>
|
|
||||||
.PP
|
|
||||||
<\fBhttps://en.wikipedia.org/wiki/Infinite_monkey_theorem\fP>
|
|
||||||
.PP
|
|
||||||
<\fBhttps://en.wikipedia.org/wiki/Weasel_program\fP>
|
|
||||||
.PP
|
|
||||||
<\fBhttps://web.archive.org/web/20180308131613/http://www.doc.ic.ac.uk/~nd/surprise_96/journal/vol1/hmw/article1.html\fP>
|
|
||||||
.SH AUTHOR
|
|
||||||
Cody Boone Ferguson <\fBweasel@xexyl.net\fP>
|
|
||||||
+4
-9
@@ -28,15 +28,10 @@ View `output.html` in a browser.
|
|||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
grep -e '[-?+*/^&|.<>=]' prog.c
|
./try.sh
|
||||||
|
|
||||||
(cd ..; ls -lS */prog.c) | \
|
|
||||||
awk 'BEGIN { print "["; } { print "{\"winner\":\"",$9,"\", \"size\":",$5,"},"} END { print "]"}' \
|
|
||||||
> ioccc.json
|
|
||||||
./prog < ioccc.json > ioccc.html
|
|
||||||
```
|
```
|
||||||
|
|
||||||
View `output.html` in a browser.
|
As the script says, open `output.html` in a browser.
|
||||||
|
|
||||||
What's not right with the output? How can one fix it?
|
What's not right with the output? How can one fix it?
|
||||||
|
|
||||||
@@ -44,7 +39,7 @@ What's not right with the output? How can one fix it?
|
|||||||
## Judges' remarks:
|
## Judges' remarks:
|
||||||
|
|
||||||
This entry exhibits a way of obfuscation we haven't seen before, we think.
|
This entry exhibits a way of obfuscation we haven't seen before, we think.
|
||||||
The rulez of programming in an imperative language are violated, aren't they?
|
The `rulez` of programming in an imperative language are violated, aren't they?
|
||||||
|
|
||||||
Try figuring out how to increase the number of different colors, if you can.
|
Try figuring out how to increase the number of different colors, if you can.
|
||||||
|
|
||||||
@@ -58,7 +53,7 @@ to generate an HTML page from a JSON feed.
|
|||||||
This entry takes such decadence to an extreme. It just calls a bunch of
|
This entry takes such decadence to an extreme. It just calls a bunch of
|
||||||
libraries to generate an HTML page from a JSON feed, literally. There is no
|
libraries to generate an HTML page from a JSON feed, literally. There is no
|
||||||
variable (function parameters included), no operator, no flow control statements
|
variable (function parameters included), no operator, no flow control statements
|
||||||
except a few decorative returns. In compliance to production coding standards,
|
except a few decorative `return`s. In compliance to production coding standards,
|
||||||
the code is littered with fashionable jargon, doxygen comment, and license text.
|
the code is littered with fashionable jargon, doxygen comment, and license text.
|
||||||
|
|
||||||
As one would expect from such an approach, this program is much more resource
|
As one would expect from such an approach, this program is much more resource
|
||||||
|
|||||||
Executable
+41
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2018/hou
|
||||||
|
#
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: grep -e '[-?+*/^&|.<>=]' prog.c (space = next page, q = quit): "
|
||||||
|
echo 1>&2
|
||||||
|
grep -e '[-?+*/^&|.<>=]' prog.c | less -EXF
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
# ^-- SC2140 (warning): Word is of the form "A"B"C" (B indicated). Did you mean "ABC" or "A\"B\"C"?
|
||||||
|
# ^-- SC1083 (warning): This { is literal. Check expression (missing ;/\n?) or quote it.
|
||||||
|
# ^-- SC1083 (warning): This } is literal. Check expression (missing ;/\n?) or quote it.
|
||||||
|
# ^-- SC2140 (warning): Word is of the form "A"B"C" (B indicated). Did you mean "ABC" or "A\"B\"C"?
|
||||||
|
# shellcheck disable=SC2140
|
||||||
|
# shellcheck disable=SC1083
|
||||||
|
echo "(cd ..; ls -lS -- */prog.c) | \
|
||||||
|
awk 'BEGIN { print "["; } { print "{\"winner\":\"",\$9,"\", \"size\":",\$5,"},"} END { print "]"}' \
|
||||||
|
> ioccc.json"
|
||||||
|
|
||||||
|
(cd ..; ls -lS -- */prog.c) | \
|
||||||
|
awk 'BEGIN { print "["; } { print "{\"winner\":\"",$9,"\", \"size\":",$5,"},"} END { print "]"}' \
|
||||||
|
> ioccc.json
|
||||||
|
./prog < ioccc.json > ioccc.html
|
||||||
|
|
||||||
|
echo 1>&2
|
||||||
|
echo "Now open ioccc.html in your browser." 1>&2
|
||||||
|
|
||||||
|
exit 0
|
||||||
+49
-34
@@ -5,26 +5,37 @@ make
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Bugs and (Mis)features:
|
||||||
|
|
||||||
|
The current status of this entry is:
|
||||||
|
|
||||||
|
```
|
||||||
|
STATUS: INABIAF - please **DO NOT** fix
|
||||||
|
```
|
||||||
|
|
||||||
|
For more detailed information see [2018 vokes in bugs.md](/bugs.md#2018-vokes).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./prog < example-1.txt
|
./prog < file.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./prog < example-2.txt
|
./try.sh
|
||||||
./prog < example-tab.txt
|
|
||||||
./prog < ioccc.txt
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Judges' remarks:
|
## Judges' remarks:
|
||||||
|
|
||||||
What this program does is not witchcraft and there are no spectres, but you
|
What this program does is not witchcraft and there are no spectres, but you
|
||||||
might have a meltdown trying to work it all out.
|
might have a meltdown trying to work it all out (look at the source code to
|
||||||
|
understand this better).
|
||||||
|
|
||||||
This entry is designed to mislead in many ways. However, if you find yourself
|
This entry is designed to mislead in many ways. However, if you find yourself
|
||||||
wanting to know the possibilities for navigating a graph, you will get the
|
wanting to know the possibilities for navigating a graph, you will get the
|
||||||
@@ -33,6 +44,7 @@ answer you seek with no hocus pocus.
|
|||||||
|
|
||||||
## Author's remarks:
|
## Author's remarks:
|
||||||
|
|
||||||
|
|
||||||
### Introduction:
|
### Introduction:
|
||||||
|
|
||||||
This program reads a directed graph (as lines with integer node IDs),
|
This program reads a directed graph (as lines with integer node IDs),
|
||||||
@@ -41,7 +53,7 @@ grouped into strongly connected components. Given a set of nodes
|
|||||||
representing targets and edges representing dependencies between them,
|
representing targets and edges representing dependencies between them,
|
||||||
it produces a build order with any dependency cycles gathered.
|
it produces a build order with any dependency cycles gathered.
|
||||||
|
|
||||||
For example, the following input (provided as `example-1.txt`):
|
For example, the following input (provided as [example-1.txt](example-1.txt)):
|
||||||
|
|
||||||
```
|
```
|
||||||
0 4 8
|
0 4 8
|
||||||
@@ -80,12 +92,14 @@ sorted order:
|
|||||||
4: 7
|
4: 7
|
||||||
```
|
```
|
||||||
|
|
||||||
It uses Tarjan's strongly connected components algorithm for the
|
It uses [Tarjan's strongly connected components
|
||||||
grouping and reverse-topological sorting, along with a bonus hidden
|
algorithm](https://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm)
|
||||||
|
for the grouping and reverse-topological sorting, along with a bonus hidden
|
||||||
implementation of counting sort, which sorts each group.
|
implementation of counting sort, which sorts each group.
|
||||||
|
|
||||||
For other details about the input format, see "Issues and
|
For other details about the input format, see [Issues and
|
||||||
Limitations".
|
Limitations](#issues-and-limitations).
|
||||||
|
|
||||||
|
|
||||||
### Building:
|
### Building:
|
||||||
|
|
||||||
@@ -104,7 +118,8 @@ Note: The program can also be built with `-std=c99` or `-std=c89`.
|
|||||||
If building with `-Weverything`, then `-Wno-strict-prototypes`
|
If building with `-Weverything`, then `-Wno-strict-prototypes`
|
||||||
may also be necessary -- the function pointer declarations for
|
may also be necessary -- the function pointer declarations for
|
||||||
`_` and `B` may get warnings otherwise, for reasons described
|
`_` and `B` may get warnings otherwise, for reasons described
|
||||||
under "Obfuscations".
|
next in [Obfuscations](#obfuscations).
|
||||||
|
|
||||||
|
|
||||||
### Obfuscations:
|
### Obfuscations:
|
||||||
|
|
||||||
@@ -117,11 +132,11 @@ under "Obfuscations".
|
|||||||
of parameters, the argument count and types are unconstrained. `_` is
|
of parameters, the argument count and types are unconstrained. `_` is
|
||||||
set to different functions in several places, but it is always called
|
set to different functions in several places, but it is always called
|
||||||
with appropriate argument(s) for its possible current functions. This
|
with appropriate argument(s) for its possible current functions. This
|
||||||
is allowed by the standard -- The section on F,I,N,D,M,Y,C,L,U,E has
|
is allowed by the standard -- The section on
|
||||||
further details.
|
`F`,`I`,`N`,`D`,`M`,`Y`,`C`,`L`,`U`,`E` has further details.
|
||||||
|
|
||||||
- It uses `_` in three different scopes: as a goto label (function
|
- It uses `_` in three different scopes: as a `goto` label (function
|
||||||
scope), as an enum name, and a `_` function pointer (which is required
|
scope), as an `enum` name, and a `_` function pointer (which is required
|
||||||
to have file scope, since it starts with `_`). There are also other
|
to have file scope, since it starts with `_`). There are also other
|
||||||
`_`s: it appears in a string, obscured by a hexadecimal escape sequence
|
`_`s: it appears in a string, obscured by a hexadecimal escape sequence
|
||||||
(`\x5f`), and the cauldron is supported by a giant underscore.
|
(`\x5f`), and the cauldron is supported by a giant underscore.
|
||||||
@@ -133,48 +148,48 @@ under "Obfuscations".
|
|||||||
functions have their names reused for different things in other
|
functions have their names reused for different things in other
|
||||||
functions.
|
functions.
|
||||||
|
|
||||||
- There is an enum early on that defines several single-letter
|
- There is an enum early on that defines several single-letter identifiers:
|
||||||
identifiers: F,I,N,D,M,Y,C,L,U,E. These are used for array offsets,
|
`F`,`I`,`N`,`D`,`M`,`Y`,`C`,`L`,`U`,`E`. These are used for array offsets,
|
||||||
both individually and in combination. The first several values are
|
both individually and in combination. The first several values are also a
|
||||||
also a clue: ISO/IEC 9899:1999 chapter 6.7.5.3 verse 14 describes how
|
clue: ISO/IEC 9899:1999 chapter 6.7.5.3 verse 14 describes how function
|
||||||
function declarators with an empty parameter list behave. (As does
|
declarators with an empty parameter list behave. (As does 3.5.4.3 for ANSI C,
|
||||||
3.5.4.3 for ANSI C, which explains the 0x3543 that appears soon
|
which explains the `0x3543` that appears soon after.)
|
||||||
after.)
|
|
||||||
|
|
||||||
- Several parts of the program's state are stashed in otherwise unused
|
- Several parts of the program's state are stashed in otherwise unused
|
||||||
offsets of the node arrays. These locations are accessed in multiple
|
offsets of the node arrays. These locations are accessed in multiple
|
||||||
ways, such as using `I[p]` (where I == 7) as well as `p[F+L]` (6+1),
|
ways, such as using `I[p]` (where `I == 7`) as well as `p[F+L]` (6+1),
|
||||||
or `b[M-N]` (14-5) and `U[b]` (where U == 9).
|
or `b[M-N]` (14-5) and `U[b]` (where `U == 9`).
|
||||||
|
|
||||||
- The other identifiers are misleading, punny, or both. `spectre` does
|
- The other identifiers are misleading, punny, or both. `spectre` does
|
||||||
not exploit CVE-2017-5753 or CVE-2017-5715, for example -- it just fits
|
not exploit CVE-2017-5753 or CVE-2017-5715, for example -- it just fits
|
||||||
the witch theme. `cast` doesn't cast, `hex` has nothing to do with
|
the witch theme. `cast` doesn't cast, `hex` has nothing to do with
|
||||||
hexadecimal, `bubble` is not bubble sort, there is no undefined
|
hexadecimal, `bubble` is not bubble sort, there is no undefined
|
||||||
behavior in `nasal_demons`, and `main` has absolutely nothing to do
|
behavior in `nasal_demons`, and `main()` has absolutely nothing to do
|
||||||
with a hand.
|
with a hand.
|
||||||
|
|
||||||
- For well-formed input, how the program determines when to exit is a
|
- For well-formed input, how the program determines when to exit is a
|
||||||
bit obscure. `main` ends with a `goto` leading back to an earlier `_`
|
bit obscure. `main()` ends with a `goto` leading back to an earlier `_`
|
||||||
label, so it just loops forever, and `exit` only appears in code paths
|
label, so it just loops forever, and `exit` only appears in code paths
|
||||||
related to error-handling. It looks like `cast` calls `meltdown` with
|
related to error-handling. It looks like `cast` calls `meltdown` with
|
||||||
its second argument set to 0, which would call `exit`, but running in
|
its second argument set to 0, which would call `exit`, but running in
|
||||||
gdb with a breakpoint on `cast` reveals that it isn't being called...
|
`gdb(1)` with a breakpoint on `cast` reveals that it isn't being called...
|
||||||
|
|
||||||
- Instead of using `isdigit()`, the program checks the numeric value of
|
- Instead of using `isdigit(3)`, the program checks the numeric value of
|
||||||
each `char`, and literals that would suggest comparing against e.g. '0'
|
each `char`, and literals that would suggest comparing against e.g. `'0'`
|
||||||
are specified in octal in one place, and produced by arithmetic using
|
are specified in octal in one place, and produced by arithmetic using
|
||||||
the enum elsewhere.
|
the `enum` elsewhere.
|
||||||
|
|
||||||
- Common conventions are subverted: `i` is not a loop index, `argv` and
|
- Common conventions are subverted: `i` is not a loop index, `argv` and
|
||||||
`argc`'s names are swapped.
|
`argc`'s names are swapped.
|
||||||
|
|
||||||
- `NULL` does not appear in the program. Instead, `argc[argv]` (which is
|
- `NULL` does not appear in the program. Instead, `argc[argv]` (which is
|
||||||
required to be a null pointer) is saved and passed to where its value
|
required to be a NULL pointer) is saved and passed to where its value
|
||||||
is needed.
|
is needed.
|
||||||
|
|
||||||
- Oh, and the program is squashed into the shape of a bubbling cauldron,
|
- Oh, and the program is squashed into the shape of a bubbling cauldron,
|
||||||
on top of a giant underscore, so there's that.
|
on top of a giant underscore, so there's that.
|
||||||
|
|
||||||
|
|
||||||
### Issues and Limitations:
|
### Issues and Limitations:
|
||||||
|
|
||||||
- Despite appearances, it does not handle numbers in hex, or provide
|
- Despite appearances, it does not handle numbers in hex, or provide
|
||||||
@@ -217,9 +232,9 @@ under "Obfuscations".
|
|||||||
nodes are visited. Addressing this would put the program over the size
|
nodes are visited. Addressing this would put the program over the size
|
||||||
limit.
|
limit.
|
||||||
|
|
||||||
- The implementation depends on the characters '0', '1', ... '9' having
|
- The implementation depends on the characters `'0'`, `'1'`, ... `'9'` having
|
||||||
the values 48 through 57, rather than using `isdigit()`. As noted
|
the values `48` through `57`, rather than using `isdigit(3)`. As noted above,
|
||||||
above, this program has nothing to do with a hand.
|
this program has nothing to do with a hand.
|
||||||
|
|
||||||
|
|
||||||
## Copyright and CC BY-SA 4.0 License:
|
## Copyright and CC BY-SA 4.0 License:
|
||||||
|
|||||||
Executable
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2018/vokes
|
||||||
|
#
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./prog < example-1.txt: "
|
||||||
|
echo 1>&2
|
||||||
|
./prog < example-1.txt
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./prog < example-2.txt: "
|
||||||
|
echo 1>&2
|
||||||
|
./prog < example-2.txt
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./prog < example-tab.txt: "
|
||||||
|
echo 1>&2
|
||||||
|
./prog < example-tab.txt
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: ./prog < ioccc.txt: "
|
||||||
|
echo 1>&2
|
||||||
|
./prog < ioccc.txt
|
||||||
@@ -1263,10 +1263,16 @@ compiled!
|
|||||||
|
|
||||||
## 1994 shapiro
|
## 1994 shapiro
|
||||||
|
|
||||||
### STATUS: missing file - please provide it
|
### STATUS: INABIAF - please **DO NOT** fix
|
||||||
### Source code: [1994/shapiro/shapiro.c](1994/shapiro/shapiro.c)
|
### Source code: [1994/shapiro/shapiro.c](1994/shapiro/shapiro.c)
|
||||||
### Information: [1994/shapiro/README.md](1994/shapiro/README.md)
|
### Information: [1994/shapiro/README.md](1994/shapiro/README.md)
|
||||||
|
|
||||||
|
This program will likely crash if the source code file (by the name of the file
|
||||||
|
that's compiled) cannot be opened in the directory it is run from.
|
||||||
|
|
||||||
|
|
||||||
|
### STATUS: missing file - please provide it
|
||||||
|
|
||||||
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) noted that the
|
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) noted that the
|
||||||
README.md file refers to an alternative version of the code that is not
|
README.md file refers to an alternative version of the code that is not
|
||||||
obfuscated but it is missing from the entry directory and the archive. Do you
|
obfuscated but it is missing from the entry directory and the archive. Do you
|
||||||
@@ -3165,6 +3171,58 @@ Abort trap: 6
|
|||||||
|
|
||||||
but this is expected and the file `ioccc.html` will be generated properly.
|
but this is expected and the file `ioccc.html` will be generated properly.
|
||||||
|
|
||||||
|
## 2018 vokes
|
||||||
|
|
||||||
|
### STATUS: INABIAF - please **DO NOT** fix
|
||||||
|
### Source code: [2018/vokes/vokes.c](2018/vokes/vokes.c)
|
||||||
|
### Information: [2018/vokes/README.md](2018/vokes/README.md)
|
||||||
|
|
||||||
|
The author wrote the following:
|
||||||
|
|
||||||
|
- Despite appearances, it does not handle numbers in hex, or provide
|
||||||
|
a `curses(3)`-based interface.
|
||||||
|
|
||||||
|
- The expected input format is zero or more lines of space-separated
|
||||||
|
integers. If other characters appear in the input, it will either
|
||||||
|
reject the input entirely and exit with a non-zero status, or skip
|
||||||
|
number(s) adjacent to the non-digit characters, depending on where the
|
||||||
|
characters appear. Tabs and multiple consecutive spaces are handled
|
||||||
|
correctly, however.
|
||||||
|
|
||||||
|
- Individual lines of input longer than `0x3543 - 1` bytes will be
|
||||||
|
split and processed as if they were multiple lines of input, which can
|
||||||
|
produce incorrect results. This magic number's significance is
|
||||||
|
described earlier.
|
||||||
|
|
||||||
|
- The algorithm expects its input to represent a fully connected graph.
|
||||||
|
While the output is otherwise topologically sorted, if there are nodes
|
||||||
|
completely unconnected to the rest of the graph (with or without
|
||||||
|
self-cycles), they will be output as soon as they are processed --
|
||||||
|
this means that, when there are disconnected nodes, reordering the
|
||||||
|
input lines can produce different output. Addressing this by adding
|
||||||
|
another pass is would put the program over the size limit.
|
||||||
|
|
||||||
|
- While the node IDs don't need to be consecutive or start at 0, the
|
||||||
|
implementation doesn't have special handling for sparse graphs. If you
|
||||||
|
give it a graph with nodes numbered 0 and 2147483647, it will attempt
|
||||||
|
to allocate sufficient memory (potentially around 32 GB) for the
|
||||||
|
entire range of graph nodes, even if those are the only ones. If
|
||||||
|
memory allocation returns NULL, it will gracefully exit, otherwise it
|
||||||
|
will succeed, eventually, perhaps after a great deal of swapping.
|
||||||
|
|
||||||
|
- Node IDs >= 2147483648 will cause the program to print an error
|
||||||
|
message and exit with a non-zero status. This shrinks the code that
|
||||||
|
detects overflowing the array size by a bit.
|
||||||
|
|
||||||
|
- A very large group of nodes in a cycle can cause a stack overflow.
|
||||||
|
This typically takes over 100,000 nodes, and depends on the order the
|
||||||
|
nodes are visited. Addressing this would put the program over the size
|
||||||
|
limit.
|
||||||
|
|
||||||
|
- The implementation depends on the characters `'0'`, `'1'`, ... `'9'` having
|
||||||
|
the values `48` through `57`, rather than using `isdigit(3)`. As noted above,
|
||||||
|
this program has nothing to do with a hand.
|
||||||
|
|
||||||
|
|
||||||
# 2019
|
# 2019
|
||||||
|
|
||||||
|
|||||||
+17
-1
@@ -3949,12 +3949,20 @@ He also added the [try.sh](/2015/yang/try.sh) script.
|
|||||||
(Linux doesn't seem to but macOS does).
|
(Linux doesn't seem to but macOS does).
|
||||||
|
|
||||||
|
|
||||||
|
## <a name="2018_ciura"></a>[2018/ciura](/2018/ciura/prog.c) ([README.md](/2018/ciura/README.md))
|
||||||
|
|
||||||
|
[Cody](#cody) added the [try.sh](/2018/ciura/try.sh) script and the PDF file,
|
||||||
|
[lexicon.pdf](/2018/ciura/lexicon.pdf), that was a dead link, restored from the
|
||||||
|
Internet Wayback Machine.
|
||||||
|
|
||||||
|
|
||||||
## <a name="2018_ferguson"></a>[2018/ferguson](/2018/ferguson/prog.c) ([README.md](/2018/ferguson/README.md))
|
## <a name="2018_ferguson"></a>[2018/ferguson](/2018/ferguson/prog.c) ([README.md](/2018/ferguson/README.md))
|
||||||
|
|
||||||
[Cody](#cody), with irony well intended :-), fixed the [test.sh
|
[Cody](#cody), with irony well intended :-), fixed the [test.sh
|
||||||
script](/2018/ferguson/test.sh) for portability, shellcheck, making it executable
|
script](/2018/ferguson/test.sh) for portability, shellcheck, making it executable
|
||||||
and other things, fixed dead links in the man page, updated the test-strings.txt
|
and other things, fixed dead links in the man page, updated the test-strings.txt
|
||||||
file and other things as well.
|
file and other things as well (like adding the [try.sh](/2018/ferguson/try.sh)
|
||||||
|
and [try.alt.sh](/2018/ferguson/try.alt.sh) scripts).
|
||||||
|
|
||||||
Landon notes that Cody will probably never finish changes in his entries and
|
Landon notes that Cody will probably never finish changes in his entries and
|
||||||
that's probably true: let's just say that for the IOCCC I'm (Cody) a weasel! :-)
|
that's probably true: let's just say that for the IOCCC I'm (Cody) a weasel! :-)
|
||||||
@@ -3966,6 +3974,14 @@ that's probably true: let's just say that for the IOCCC I'm (Cody) a weasel! :-)
|
|||||||
[Cody](#cody) added explicit linking of libm (`-lm`) for systems that do not do this
|
[Cody](#cody) added explicit linking of libm (`-lm`) for systems that do not do this
|
||||||
(Linux doesn't seem to but macOS does).
|
(Linux doesn't seem to but macOS does).
|
||||||
|
|
||||||
|
Cody also added the [try.sh](/2018/hou/try.sh) script.
|
||||||
|
|
||||||
|
|
||||||
|
## <a name="2018_vokes"></a>[2018/vokes](/2018/vokes/prog.c) ([README.md](/2018/vokes/README.md))
|
||||||
|
|
||||||
|
[Cody](#cody) added the [try.sh](/2018/vokes/try.sh) script.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# <a name="2019"></a>2019
|
# <a name="2019"></a>2019
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user