diff --git a/2018/burton1/README.md b/2018/burton1/README.md
index 847c21fce..c0b8100f1 100644
--- a/2018/burton1/README.md
+++ b/2018/burton1/README.md
@@ -24,8 +24,8 @@ make
### Alternate code:
-An alternate version of this entry, `prog.alt.c`, is provided
-This alternate code was supposed compile without warnings, however
+An alternate version of this entry, [prog.alt.c](prog.alt.c), is provided
+This alternate code was supposed to compile without warnings, however
with modern compilers this is no longer the case.
To compile this alternate version:
@@ -42,7 +42,7 @@ One line, one array, one loop and one statement but it prints many bytes. It won
Feed this anything on stdin.
-The included script may be used as a driver program for this entry.
+The [included script](scripthd) may be used as a driver program for this entry.
It adds several nice-to-have features, and allows salt-to-taste customizability.
This code has been compiled and tested on:
@@ -57,21 +57,25 @@ This code has been compiled and tested on:
Spoiler below; scroll down.
-### SPOILER
+### SPOILER:
This started life as a personal challenge: write the shortest hex dump utility in C.
The self-imposed ground rules in the hunt for shortest:
-the code has to output correctly,
-no extraneous newlines, the code must be portable,
-and without bypassing the solution using execve(2),
-or functions built upon it (system(3), popen(3), etc). E.g:
+
+- the code has to output correctly,
+- no extraneous newlines, the code must be portable,
+and without bypassing the solution using execve(2), or functions built upon it (system(3), popen(3), etc).
+
+E.g:
+
```c
main(){system("hd");} // it's turtles all the way down!
```
is not acceptable.
+
And, "output correctly" is the output format of this entry. QED.
Early attempts ended up at a reasonably short 157 characters.
@@ -79,6 +83,7 @@ This was too long for a one-liner, so it had to be formatted as something more i
This solution is pleasing, but a true one-liner was the hoped-for goal.
Here is the 157 character version in it's entirety:
+
```c
char O,o[ 20];L(O){
putchar ( O+ 48+39 *(9<
@@ -153,67 +158,70 @@ An obfuscated hex dump has been done before:
[1986/bright/bright.c](http://ioccc.org/1986/bright/bright.c) is similar in function,
but it uses more characters in just setting up its obfuscation than this entire solution!
-### BIGGER SPOILER
+### BIGGER SPOILER:
If you are unhappy with the way DEL (character 127) is handled,
replace the cryptic expression `4<(4^l>>5)?l:46` with `32>l|l>126?46:l`.
Both take the same number of characters, but the former is a bit more interesting.
Bonus question: how does the first expression work?
-### BIGGEST SPOILER (and some history)
+### BIGGEST SPOILER (and some history):
-Technically, `char o[0];` is illegal (SS 6.7.6.2) according to ISO (N1570).
-And `char o[];` is a conditionally supported feature (SS 6.7.6.2, 6.10.8.3).
-However, it works in modern C implementations as an extension,
-including GCC, Clang and TCC, for X86 and ARM,
-on multiple operating systems (Linux, OSX, FreeBSD), so it is _functionally_ correct.
-MicroSoft Visual C++ does not allow `char o[]` or `char o[0]`,
-and implements its close relative `char o[1]`
-such that writing more than a single char will cause a fault, which is _technically_ correct.
+Technically, `char o[0];` is illegal (SS 6.7.6.2) according to ISO (N1570). And
+`char o[];` is a conditionally supported feature (SS 6.7.6.2, 6.10.8.3).
+However, it works in modern C implementations as an extension, including GCC,
+Clang and TCC, for X86 and ARM, on multiple operating systems (Linux, OSX,
+FreeBSD), so it is _functionally_ correct. MicroSoft Visual C++ does not allow
+`char o[]` or `char o[0]`, and implements its close relative `char o[1]` such
+that writing more than a single char will cause a fault, which is _technically_
+correct.
-But how does this work at all, even as an extension?
-`o[]` allocates one(!) byte in a zero-filled data area (formerly BSS).
-The UNIX-derived systems this code was run upon all place the
-storage of `O` and `o` into a zero-filled VM page with nothing following:
-thus, there are plenty of available and unused zero bytes following `O`, addressed via `o`,
-and this code only needs 17.
-This is _undefined_ behavior, but as shown, it is widely available.
+But how does this work at all, even as an extension? `o[]` allocates one(!)
+byte in a zero-filled data area (formerly
+[BSS](https://en.wikipedia.org/wiki/.bss)). The UNIX-derived systems this code
+was run upon all place the storage of `O` and `o` into a zero-filled VM page
+with nothing following: thus, there are plenty of available and unused zero
+bytes following `O`, addressed via `o`, and this code only needs 17. This is
+_undefined_ behavior, but as shown, it is widely available.
The [1979 Seventh Edition UNIX][1] (v7) system pre-dates the IOCCC by several years,
and the source code to `sh`(1) was a [significant inspiration for this contest][2].
There are two C compilers present: `cc` written by Dennis Ritchie, and `pcc` written by Steven Johnson.
The nested conditional expressions in 116 and smaller are too complex for `cc` ("Illegal conditional")
-but `pcc` handles them correctly, and neither compiler accepts `char o[]` or `char o[0]` nor puts the bytes in
-a zero-filled page (as a paged VM was not yet written for UNIX).
+but `pcc` handles them correctly, and neither compiler accepts `char o[]` or
+`char o[0]` and neither put the bytes in a zero-filled page (as a paged VM was
+not yet written for UNIX).
[1]: http://minnie.tuhs.org/cgi-bin/utree.pl
[2]: http://ioccc.org/all/README
-[3]: http://www.computerworld.com.au/article/279011/a-z_programming_languages_bourne_shell_sh/?pp=4
+[3]: https://web.archive.org/web/20180521074522/http://www.computerworld.com.au/article/279011/a-z_programming_languages_bourne_shell_sh/?pp=4
-More significant is that v7 `printf`(3) does not report the number of characters written,
-and therefore 111 compiles but does not work correctly;
-113 is the shortest code that compiles and runs correctly in Ancient UNIX.
+More significant is that v7 `printf`(3) does not report the number of characters
+written, and therefore 111 compiles but does not work correctly; 113 is the
+shortest code that compiles and runs correctly in Ancient UNIX.
-> Interesting digression: v7 `printf` (`_doprnt`) was written in PDP-11 assembler.
-> It pre-dates `varargs.h`, and assembly was the only way to gain access to the variable argument types.
-> The first edition _The C Programming Language_, 1978, page 71, remarks:
+Interesting digression: v7 `printf` (`_doprnt`) was written in PDP-11 assembly.
+It pre-dates `varargs.h`, and assembly was the only way to gain access to the
+variable argument types. The first edition _The C Programming Language_, 1978,
+page 71, remarks:
->> By the way, there is no entirely satisfactory way to write a portable function
->> that accepts a variable number of arguments, because there is no portable way
->> for the called function to determine how many arguments where actually passed to it in a given call.
->> ...
->> `printf`, the most common C function with a variable number of arguments,
->> ... is also non-portable and must be modified for different environments.
+> By the way, there is no entirely satisfactory way to write a portable function
+> that accepts a variable number of arguments, because there is no portable way
+> for the called function to determine how many arguments where actually passed
+> to it in a given call.
+> ...
+> `printf`, the most common C function with a variable number of arguments,
+> ... is also non-portable and must be modified for different environments.
-> It is fascinating to explore the roots of C through the history of the operating system
-> it was birthed within. C is often criticized as a difficult, inscrutable language,
-> but as this contest demonstrates, this is in parody.
-> _Shell-gol_ is one of those instances where someone [preferred a different language][3],
-> and (ab)used the preprocessor to re-mold C into something they found comfortable.
-> Most of the rest of the system, especially in the kernel,
-> are models of clarity and efficient expression.
+It is fascinating to explore the roots of C through the history of the operating
+system it was birthed within. C is often criticized as a difficult, inscrutable
+language, but as this contest demonstrates, this is in parody. _Shell-gol_ is
+one of those instances where someone [preferred a different language][3], and
+(ab)used the preprocessor to re-mold C into something they found comfortable.
+Most of the rest of the system, especially in the kernel, are models of clarity
+and efficient expression.
-### TL;DR
+### TL;DR:
So which version is the shortest, portable hex dump?
@@ -222,16 +230,16 @@ So which version is the shortest, portable hex dump?
* 113 works on Ancient UNIX and the portable C compiler.
* 119 works on all platforms, including the original Ritchie PDP-11 C compiler.
-### Coda
+### Coda:
Clearly, the smallest possible program violates modern best practice.
It is not even possible to compile cleanly, but it will compile correctly.
-Included is `prog.alt.c`, a modern C implementation that is -- perhaps -- the smallest,
-clean-compiling version using `clang` or `gcc` with `-Wall -pedantic`.
-Note that while this is larger than all but the original attempt,
-it will *not* work with the original Ritchie PDP-11 C compiler,
-since the expression within the ternary remains too complex.
+Included is [prog.alt.c](prog.alt.c), a modern C implementation that is --
+perhaps -- the smallest, clean-compiling version using `clang` or `gcc` with
+`-Wall -pedantic`. Note that while this is larger than all but the original
+attempt, it will *not* work with the original Ritchie PDP-11 C compiler, since
+the expression within the ternary remains too complex.
Try:
diff --git a/2018/burton1/scripthd b/2018/burton1/scripthd
index 3133ed75a..de09af623 100755
--- a/2018/burton1/scripthd
+++ b/2018/burton1/scripthd
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
-hd=${HD:=prog}
+hd=${HD:=./prog}
cat $* |
$hd |