From a3eb5340d7c9d836d9d81371becc417e38800358 Mon Sep 17 00:00:00 2001
From: Cody Boone Ferguson <53008573+xexyl@users.noreply.github.com>
Date: Mon, 11 Dec 2023 06:07:31 -0800
Subject: [PATCH] Add 2018/vokes/try.sh + format/typo checks
The bugs.md file was also updated with INABIAF status.
---
2018/vokes/README.md | 83 ++++++++++++++++++++++++++------------------
2018/vokes/try.sh | 32 +++++++++++++++++
bugs.md | 52 +++++++++++++++++++++++++++
thanks-for-help.md | 6 ++++
4 files changed, 139 insertions(+), 34 deletions(-)
create mode 100755 2018/vokes/try.sh
diff --git a/2018/vokes/README.md b/2018/vokes/README.md
index 7817de857..fd304dd3e 100644
--- a/2018/vokes/README.md
+++ b/2018/vokes/README.md
@@ -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:
```sh
-./prog < example-1.txt
+./prog < file.txt
```
### Try:
```sh
-./prog < example-2.txt
-./prog < example-tab.txt
-./prog < ioccc.txt
+./try.sh
```
## Judges' remarks:
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
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:
+
### Introduction:
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,
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
@@ -80,12 +92,14 @@ sorted order:
4: 7
```
-It uses Tarjan's strongly connected components algorithm for the
-grouping and reverse-topological sorting, along with a bonus hidden
+It uses [Tarjan's strongly connected components
+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.
-For other details about the input format, see "Issues and
-Limitations".
+For other details about the input format, see [Issues and
+Limitations](#issues-and-limitations).
+
### 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`
may also be necessary -- the function pointer declarations for
`_` and `B` may get warnings otherwise, for reasons described
-under "Obfuscations".
+next in [Obfuscations](#obfuscations).
+
### Obfuscations:
@@ -117,11 +132,11 @@ under "Obfuscations".
of parameters, the argument count and types are unconstrained. `_` is
set to different functions in several places, but it is always called
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
- further details.
+ is allowed by the standard -- The section on
+ `F`,`I`,`N`,`D`,`M`,`Y`,`C`,`L`,`U`,`E` has further details.
-- It uses `_` in three different scopes: as a goto label (function
- scope), as an enum name, and a `_` function pointer (which is required
+- It uses `_` in three different scopes: as a `goto` label (function
+ scope), as an `enum` name, and a `_` function pointer (which is required
to have file scope, since it starts with `_`). There are also other
`_`s: it appears in a string, obscured by a hexadecimal escape sequence
(`\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.
-- There is an enum early on that defines several single-letter
- identifiers: 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
- also a clue: ISO/IEC 9899:1999 chapter 6.7.5.3 verse 14 describes how
- function declarators with an empty parameter list behave. (As does
- 3.5.4.3 for ANSI C, which explains the 0x3543 that appears soon
- after.)
+- There is an enum early on that defines several single-letter identifiers:
+ `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 also a
+ clue: ISO/IEC 9899:1999 chapter 6.7.5.3 verse 14 describes how function
+ declarators with an empty parameter list behave. (As does 3.5.4.3 for ANSI C,
+ which explains the `0x3543` that appears soon after.)
- Several parts of the program's state are stashed in otherwise unused
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),
- or `b[M-N]` (14-5) and `U[b]` (where U == 9).
+ 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`).
- The other identifiers are misleading, punny, or both. `spectre` does
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
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.
- 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
related to error-handling. It looks like `cast` calls `meltdown` with
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
- each `char`, and literals that would suggest comparing against e.g. '0'
+- Instead of using `isdigit(3)`, the program checks the numeric value of
+ each `char`, and literals that would suggest comparing against e.g. `'0'`
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
`argc`'s names are swapped.
- `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.
- Oh, and the program is squashed into the shape of a bubbling cauldron,
on top of a giant underscore, so there's that.
+
### Issues and Limitations:
- 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
limit.
-- The implementation depends on the characters '0', '1', ... '9' having
- the values 48 through 57, rather than using `isdigit()`. As noted
- above, this program has nothing to do with a hand.
+- 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.
## Copyright and CC BY-SA 4.0 License:
diff --git a/2018/vokes/try.sh b/2018/vokes/try.sh
new file mode 100755
index 000000000..a0ea4684b
--- /dev/null
+++ b/2018/vokes/try.sh
@@ -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
diff --git a/bugs.md b/bugs.md
index 0cd52b439..3c11c3e49 100644
--- a/bugs.md
+++ b/bugs.md
@@ -3171,6 +3171,58 @@ Abort trap: 6
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
diff --git a/thanks-for-help.md b/thanks-for-help.md
index 3fa1b9353..a3b85ceb0 100644
--- a/thanks-for-help.md
+++ b/thanks-for-help.md
@@ -3967,6 +3967,12 @@ that's probably true: let's just say that for the IOCCC I'm (Cody) a weasel! :-)
(Linux doesn't seem to but macOS does).
+## [2018/vokes](/2018/vokes/prog.c) ([README.md](/2018/vokes/README.md))
+
+[Cody](#cody) added the [try.sh](/2018/vokes/try.sh) script.
+
+
+
# 2019