Merge pull request #1381 from xexyl/schweikh396

This commit is contained in:
Landon Curt Noll authored and GitHub committed 2023-11-11 13:46:39 -07:00
commit eea56a79ab
33 files changed
+463 -229

No files matched your search

-1
View File
@@ -15,7 +15,6 @@ The current status of this entry is:
```
STATUS: INABIAF - please **DO NOT** fix
STATUS: known bug - please help us fix
```
For more detailed information see [1994 dodsond2 in bugs.md](/bugs.md#1994-dodsond2).
+6 -6
View File
@@ -15,7 +15,7 @@
#define M isdigit
#define N 30
#define P getchar()
G a[N][3],b[N],c[N],d[N],e[N],f[N],g[N],i=W>0?W:0,j=(W>0?W:0)*20,k,l=0;
G a[N][3],b[N],c[N],d[N],e[N],f[N],g[N],i=W>0?W:0,j=0,X=0,Y=W>0?W:0,k,l=0;
main(){m();n();A;}m(){G o;srandom(getpid());do{I(o=0;
o<N;e[o++]=3){J(o,0)=J(o,1)=J(o,2)=-1;c[o]=d[o]=g[o]=0;
b[o]=N*2;}r(0);s();}F(s());t();}s(){G o,p;I(o=0;o<N;o++){
@@ -30,11 +30,11 @@ J(x,e[x])=y;J(y,e[y])=x;K(!r(y)){J(x,e[x])=J(y,e[y])=-1;(e[y])++;
(e[x])++;}L t=0;}H(1);}n(){G r,n;char v;do{r=D;}
F(c[r]||d[r]||(b[r]<3)||d[J(r,0)]||d[J(r,1)]||d[J(r,2)]||
c[J(r,0)]||c[J(r,1)]||c[J(r,2)]);F(1){E"You are in room %d\n",r);
K(f[r]){i++;E"You found an arrow\n");j+=20;f[r]=0;}K(b[r]==0){
K(f[r]){i++;E"You found an arrow\n");Y++;j+=20;f[r]=0;Y++;}K(b[r]==0){
E"Wumpus meat\n");j-=100;A;}K(d[r]){E"You fell in a pit\n");j-=50;
A;}K(r==k){K(i){i--;l++;j-=20;E"You are missing an arrow!\n");
}K(l==3+(W>0?W:0)){E"You catch the robber and recover all %d arrows!\n",(W>0?W:0)+3);
i=(W>0?W:0)+3;j+=200;k=-1;}L{E"The robber scurries away\n");do{k=D;}
}K(l&&l==Y-X){E"You catch the robber and recover all %d arrow%s!\n",Y-X,Y-X!=1?"s":"");
i=l;l=Y=X=0;j+=200;k=-1;}L{E"The robber scurries away\n");do{k=D;}
F((c[k])||(d[k])||(b[k]==0)||(k==r));}}K(c[r]){c[r]=0;c[D]=1;r=D;
E"The bats pick you up and drop you in room %d\n",r);j-=10;}L{
K(b[r]<3)E"You smell a wumpus\n");
@@ -45,11 +45,11 @@ K(!g[r]){j+=10;g[r]=1;}do{v=P;K(v=='s')q(r);K(v=='l')break;
K(v=='i')E"You have %d arrow%c\n",i,i-1?'s':' ');K(v=='q')A;}
F(!M(v));K(M(v)){n=v-'0';v=P;K(M(v))n=n*10+v-'0';
K((J(r,0)==n)||(J(r,1)==n)||(J(r,2)==n))r=n;}}}}q(r)G r;{G z,n;
char v;K(i==0){E"You have no arrows\n");H;}i--;
char v;K(i==0){E"You have no arrows\n");H;}i--;X++;
E"Shoot into which rooms? ");I(z=0;z<4;z++){j-=20*z;do{v=P;
K((v=='\n')&&(i>0)){j-=50;E"You have %d arrow%c\n",i,i-1?'s':' ');H;}else K(i==0)H;}F(!M(v));
n=v-'0';v=P;K(M(v))n=10*n+v-'0';K((J(r,0)==n)||(J(r,1)==n)||(J(r,2)
==n)){r=n;K(b[r]==0){E"You have killed the Wumpus!\n");j+=500+i*100;
A;}}L K(random()%3==1){E"The arrow bounces back and kills you\n");
j-=100;A;}L{I(n=0;n<N;n++)b[n]=2*N;w(D,0);j-=100;}K(v=='\n'){j-=50;
E"You have %d arrows\n",i);H;}}}
E"You have %d arrow%s\n",i,i!=1?"s":"");H;}}}
+6 -6
View File
@@ -15,7 +15,7 @@
#define M isdigit
#define N 30
#define P getchar()
G a[N][3],b[N],c[N],d[N],e[N],f[N],g[N],i,j=0,k,l=0;
G a[N][3],b[N],c[N],d[N],e[N],f[N],g[N],i,j=0,X=0,Y=0,k,l=0;
main(){m();n();A;}m(){G o;srandom(getpid());do{I(o=0;
o<N;e[o++]=3){J(o,0)=J(o,1)=J(o,2)=-1;c[o]=d[o]=g[o]=0;
b[o]=N*2;}r(0);s();}F(s());t();}s(){G o,p;I(o=0;o<N;o++){
@@ -30,11 +30,11 @@ J(x,e[x])=y;J(y,e[y])=x;K(!r(y)){J(x,e[x])=J(y,e[y])=-1;(e[y])++;
(e[x])++;}L t=0;}H(1);}n(){G r,n;char v;do{r=D;}
F(c[r]||d[r]||(b[r]<3)||d[J(r,0)]||d[J(r,1)]||d[J(r,2)]||
c[J(r,0)]||c[J(r,1)]||c[J(r,2)]);F(1){E"You are in room %d\n",r);
K(f[r]){i++;E"You found an arrow\n");j+=20;f[r]=0;}K(b[r]==0){
K(f[r]){i++;E"You found an arrow\n");Y++;j+=20;f[r]=0;}K(b[r]==0){
E"Wumpus meat\n");j-=100;A;}K(d[r]){E"You fell in a pit\n");j-=50;
A;}K(r==k){K(i){i--;l++;j-=20;E"You are missing an arrow!\n");
}K(l==3){E"You catch the robber and recover all 3 arrows!\n");
i=3;j+=200;k=-1;}L{E"The robber scurries away\n");do{k=D;}
}K(l&&l==Y-X){E"You catch the robber and recover all %d arrow%s!\n",Y-X,Y-X!=1?"s":"");
i=l;l=Y=X=0;j+=200;k=-1;}L{E"The robber scurries away\n");do{k=D;}
F((c[k])||(d[k])||(b[k]==0)||(k==r));}}K(c[r]){c[r]=0;c[D]=1;r=D;
E"The bats pick you up and drop you in room %d\n",r);j-=10;}L{
K(b[r]<3)E"You smell a wumpus\n");
@@ -45,11 +45,11 @@ K(!g[r]){j+=10;g[r]=1;}do{v=P;K(v=='s')q(r);K(v=='l')break;
K(v=='i')E"You have %d arrow%c\n",i,i-1?'s':' ');K(v=='q')A;}
F(!M(v));K(M(v)){n=v-'0';v=P;K(M(v))n=n*10+v-'0';
K((J(r,0)==n)||(J(r,1)==n)||(J(r,2)==n))r=n;}}}}q(r)G r;{G z,n;
char v;K(i==0){E"You have no arrow\n");H;}i--;
char v;K(i==0){E"You have no arrow\n");H;}i--;X++;
E"Shoot into which rooms? ");I(z=0;z<4;z++){j-=20*z;do{v=P;
K((v=='\n')&&(i>0)){j-=50;E"You have %d arrow%c\n",i,i-1?'s':' ');H;}else K(i==0)H;}F(!M(v));
n=v-'0';v=P;K(M(v))n=10*n+v-'0';K((J(r,0)==n)||(J(r,1)==n)||(J(r,2)
==n)){r=n;K(b[r]==0){E"You have killed the Wumpus!\n");j+=500+i*100;
A;}}L K(random()%3==1){E"The arrow bounces back and kills you\n");
j-=100;A;}L{I(n=0;n<N;n++)b[n]=2*N;w(D,0);j-=100;}K(v=='\n'){j-=50;
E"You have %d arrows\n",i);H;}}}
E"You have %d arrow%s\n",i,i!=1?"s":"");H;}}}
+2 -2
View File
@@ -3,8 +3,8 @@ august.oc
test.oo
fac.oo
parse.oo
prog.oc
august.oc
august.oo
august.oo
prog.oo
august.orig
prog.orig
+20 -28
View File
@@ -34,13 +34,7 @@ The above should print a `!` followed by a newline.
### Try:
```sh
cat august.c fac.oc | ./august > fac.oo
./august < fac.oo
cat august.c fac.oc | ./august | ./august
cat august.c parse.oc | ./august > parse.oo
cat parse.oo fac.oc | ./august | ./august
./try.sh
```
@@ -79,13 +73,6 @@ And if you have lots of spare time, you can recurse one level deeper:
cat august.oo august.oo august.oo fac.oo | ./august
```
NOTE: to run all the commands in the above sections you can also use the
[try.sh](try.sh) script like:
```sh
./try.sh
```
We (the judges) recommend that you spend some time studying this
entry as it surely will make the 'best of the IOCCC' list. It was
very well received by those who attended the IOCCC BOF.
@@ -108,8 +95,8 @@ compiler that compiles from OC (Obfuscated C, a subset of C) into the
byte code that the interpreter understands.
The language the compiler understands is a subset of C (the grammar
is in grammar.small) with the functions getchar() and putchar()
available. The subset has the types `int', `char', and pointers to
is below) with the functions `getchar(3)` and `putchar(3)`
available. The subset has the types `int`, `char`, and pointers to
those (it has function pointers too, but not with the proper
syntax). Arrays can only be global. There is a rather limited set
of operators, and control constructs.
@@ -117,10 +104,10 @@ of operators, and control constructs.
The compiler has absolutely no error checking, so things
can go wrong. But this is what seasoned C programmers are used to.
Assume that the interpreter has been compiled (source in prog.c and
binary in prog) and that we have this in a file named `test.oc`:
Assume that the interpreter has been compiled (source in [august.c](august.c)
and binary in august) and that we have this in a file named `test.oc`:
```
```c
main() { putchar('!'); putchar('\n'); exit(0); }
```
@@ -155,22 +142,26 @@ command from the Makefile, but add the `-E` flag and change 60000 to 40000,
i.e.:
```sh
cc -E -DZ=40000 .... august.c > prog.oc
cc -E -DZ=40000 .... august.c > august.oc
```
If `prog.oc` contain some junk line starting with a `#' (most likely
it does) then remove it.
If `august.oc` contain some junk line starting with a `#` (most likely
it does) then remove it like:
```sh
sed -i'' '/^#/d' august.oc
```
OK, we can now compile the interpreter:
```sh
cat august.c prog.oc | ./august > prog.oo
cat august.c august.oc | ./august > august.oo
```
And we can run it:
```sh
cat prog.oo test.oo | ./august
cat august.oo test.oo | ./august
```
Here we have the interpreter interpreting another interpreter that runs
@@ -178,13 +169,13 @@ the program. Did you think that was too fast? Just throw in another
level of interpretation:
```sh
cat prog.oo prog.oo test.oo | ./august
cat august.oo august.oo test.oo | ./august
```
And another...
```sh
cat prog.oo prog.oo prog.oo test.oo | ./august
cat august.oo august.oo august.oo test.oo | ./august
```
---
@@ -199,7 +190,7 @@ Anyway, the bytecode from the compiler is first optimized in
an external optimizer (not supplied here); this brings down the
size of it by about 30%. The remaining code is then LZ-compressed
(roughly) with a sliding window of 255 bytes. The most common
occuring bytes are then encoded using `" \n\t;{}"` to avoid having
occurring bytes are then encoded using `" \n\t;{}"` to avoid having
them counted as significant. About 200 bytes of the interpreter
handles the unpacking of the byte code (this is a lot, but it pays
off).
@@ -208,7 +199,7 @@ Despite all this work I still had to put a lot of code in the
compilation command. This disturbs me. It is possible to compress
the code further with a better entropy coder (e.g. an arithmetic
coder), but decompression then takes up too much code. Maybe this
would be a way to fit it all into the 1536 bytes, but I'm don't have
would be a way to fit it all into the 1536 bytes, but I don't have
time to try it.
---
@@ -283,6 +274,7 @@ stars: "*"*
---
Well, that is enough ranting for now.
+1
View File
@@ -14,6 +14,7 @@ cat parse.oo fac.oc | ./august | ./august
rm august.oc
make august.oc
sed -i'' '/^#/d' august.oc
cat august.c august.oc | ./august > august.oo
cat august.oo test.oo | ./august
cat august.oo august.oo fac.oo | ./august
-2
View File
@@ -66,9 +66,7 @@ where `a==0`.
4. The fact that `main()` is a single expression and so beautifies poorly.
5. The fact that `main()` is used:
- to compute powers in modular arithmetic.
- to recursively call itself in the main loop.
+11 -11
View File
@@ -1,16 +1,16 @@
int cain(int I, char **O, int O0, int OO, int l)
int pain(int I, char **O, int O0, int OO, int l)
{
return !!I>=I?!I>=I?!!~I>=~I?!~I>=~I?!OO?!I:OO%2?
OO=cain(I,O,O0,OO>>!!OO,l),
OO=cain(I-!I-!!I,O,OO,OO,l),
OO=cain(I-!I-!!I,O,O0,OO,l),
OO=pain(I,O,O0,OO>>!!OO,l),
OO=pain(I-!I-!!I,O,OO,OO,l),
OO=pain(I-!I-!!I,O,O0,OO,l),
!(OO-!I||I)?l-1:OO
:(OO=cain(I,O,O0,OO>>!!OO,l),
!(OO-l+!I||I)?l-1:cain(I-!I-!!I,O,OO,OO,l))
:(OO=pain(I,O,O0,OO>>!!OO,l),
!(OO-l+!I||I)?l-1:pain(I-!I-!!I,O,OO,OO,l))
:(O0+OO)%l
:cain(I-I/I-I/I,O,O0,OO+OO/OO,
cain(0,O,O0,OO,I-I-I)+I+1?1:printf("%d\n",I-I-I)+fflush(stdout))
:cain(I-I-I-I-I,O,I+I-I+I,I,0)
:cain(~!!I-!!I,O,atoi(1[O]),1,atoi(0[O]));
:pain(I-I/I-I/I,O,O0,OO+OO/OO,
pain(0,O,O0,OO,I-I-I)+I+1?1:printf("%d\n",I-I-I)+fflush(stdout))
:pain(I-I-I-I-I,O,I+I-I+I,I,0)
:pain(~!!I-!!I,O,atoi(1[O]),1,atoi(0[O]));
}
int main(int I, char **O) { int O0=0,OO=0,l=0; return cain(I,O,O0,OO,l); }
int main(int I, char **O) { int O0=0,OO=0,l=0; return pain(I,O,O0,OO,l); }
+1 -1
View File
@@ -62,7 +62,7 @@ CDEFINE= -DZ=35000
# Include files that are needed to compile
#
CINCLUDE=
CINCLUDE= -include stdio.h -include unistd.h
# Optimization
#
+9 -2
View File
@@ -36,12 +36,19 @@ make CFLAGS+="-DZ=20000" clobber alt
Besides the fact that modern systems make it impossible to see what this program
does the rapid movement can be a problem for some people. It is for these
reasons that we recommend you first try the alternate version as described
above. If however you wish to see the original version in modern systems, try:
above.
### Original build:
If however you wish to see the original version in modern systems, try:
```sh
make all
```
### Original use:
Use `./eldby` as you would `./eldby.alt` above.
@@ -55,7 +62,7 @@ in a very small chunk of code.
This program shows flying spheres. The program eats CPU on lesser
equipped systems. The program will run until termination. Terminal
must be vt100 or better with 80 columns and 24 rows or more.
must be VT100 or better with 80 columns and 24 rows or more.
## Copyright and CC BY-SA 4.0 License:
-2
View File
@@ -1,5 +1,3 @@
#include <stdio.h>
#include <unistd.h>
float s=1944,x[5],y[5],z[5],r[5],j,h,a,b,d,e;int i=33,c,l,f=1;int g(){return f=
(f*6478+1)%65346;}m(){x[i]=g()-l;y[i]=(g()-l)/4;r[i]=g()>>4;}main(){char t[1948
]=" `MYmtw%FFlj%Jqig~%`jqig~Etsqnsj3stb",*p=t+3,*k="3tjlq9TX";l=s*20;while(i<s)
+1 -1
View File
@@ -39,7 +39,7 @@ include ../../var.mk
# Common C compiler warnings to silence
#
CSILENCE= -Wno-error -Wno-implicit-function-declaration -Wno-keyword-macro \
-Wno-shift-op-parentheses -Wno-unused-parameter \
-Wno-shift-op-parentheses -Wno-unused-parameter -Wno-implicit-int \
-Wno-deprecated-non-prototype -Wno-strict-prototypes -Wno-unsequenced
# Common C compiler warning flags
+6 -11
View File
@@ -26,21 +26,16 @@ For more detailed information see [1996 gandalf in bugs.md](/bugs.md#1996-gandal
### Try:
```sh
PATH=.:$PATH
./hatcat
./cathat
./try.sh
```
And next try:
As the script asks, care to guess why these execute differently? Only the
compiler knows ... ok maybe other things like the author, the judges and perhaps
you too?
```sh
./cathat
`pwd`/cathat
```
BTW: it is perilous to 'try' the patience of
[Gandalf](https://www.glyphweb.com/arda/g/gandalf.html). Go ahead, 'try' it! :-)
Care to guess why these execute differently? Only the
compiler knows ... ok maybe other things like the author,
the judges and maybe you too?
## Judges' remarks:
+104
View File
@@ -0,0 +1,104 @@
#!/usr/bin/env bash
make all 1>/dev/null || exit 1
# remove temporary files to show later
rm -f hatcat.txt cathat.txt hatcat2.txt cathat2.txt hatcat3.txt cathat3.txt
trap 'rm -f hatcat.txt cathat.txt hatcat2.txt cathat2.txt hatcat3.txt cathat3.txt; exit' 0 1 2 3 15
delete_tmp_files()
{
rm -f hatcat.txt cathat.txt hatcat2.txt cathat2.txt hatcat3.txt cathat3.txt
return 0
}
press_any_key()
{
echo 1>&2
read -r -n 1 -p "Press any key to continue (q = quit): " 1>&2
test "$REPLY" = "q" && delete_tmp_files && echo 1>&2 && exit
}
show_diff()
{
if [[ "$#" -ne 2 ]]; then
echo "$0: show_diff expects two args, got: $#" 1>&2
exit 1
fi
echo "$ diff $1 $2" 1>&2
diff "$1" "$2" && echo "$1 and $2 are identical"
}
echo "Notice how the programs are the same:" 1>&2
diff -s hatcat cathat
press_any_key
echo "Now notice how running both cathat and hatcat in different ways" 1>&2
echo "shows different output." 1>&2
press_any_key
echo "Running hatcat without a path:" 1>&2
echo "$ PATH=.:\$PATH" 1>&2
PATH=.:$PATH
echo "$ hatcat | tee hatcat.txt" 1>&2
hatcat | tee hatcat.txt
press_any_key
echo "Running cathat without a path:" 1>&2
echo "$ cathat | tee cathat.txt" 1>&2
cathat | tee cathat.txt
press_any_key
echo "Showing diff between the above two commands, 'hatcat' and './cathat':" 1>&2
show_diff hatcat.txt cathat.txt
press_any_key
echo "Now watch ./hatcat:" 1>&2
./hatcat | tee hatcat2.txt
press_any_key
echo "Now watch ./cathat:" 1>&2
./cathat | tee cathat2.txt
press_any_key
echo "Showing diff between running 'hatcat' and './hatcat':" 1>&2
show_diff hatcat.txt hatcat2.txt
press_any_key
echo "Now watch \$(pwd)/cathat" 1>&2
"$(pwd)"/cathat | tee cathat3.txt
press_any_key
echo "Finally, watch \$(pwd)/hatcat" 1>&2
"$(pwd)"/hatcat | tee hatcat3.txt
press_any_key
echo "Showing diff between running './hatcat' and './cathat':" 1>&2
show_diff hatcat2.txt cathat2.txt
press_any_key
echo "Showing diff between running '\$(pwd)/hatcat' and '\$(pwd)/cathat':" 1>&2
show_diff hatcat3.txt cathat3.txt
press_any_key
echo "Showing diff between running '\$(pwd)/hatcat' and 'hatcat':" 1>&2
show_diff hatcat3.txt hatcat.txt
press_any_key
echo "Showing diff between running '\$(pwd)/hatcat' and './hatcat':" 1>&2
show_diff hatcat3.txt hatcat2.txt
press_any_key
echo "Showing diff between running '\$(pwd)/cathat' and 'cathat':" 1>&2
show_diff cathat3.txt cathat.txt
press_any_key
echo "Showing diff between running '\$(pwd)/cathat' and './cathat':" 1>&2
show_diff cathat3.txt cathat2.txt
press_any_key
# remove temporary files
rm -f hatcat.txt cathat.txt hatcat2.txt cathat2.txt hatcat3.txt cathat3.txt
echo 1>&2
echo "Now answer: why did some of the same programs execute differently?" 1>&2
+1 -1
View File
@@ -62,7 +62,7 @@ CDEFINE=
# Include files that are needed to compile
#
CINCLUDE=
CINCLUDE= -include stdio.h
# Optimization
#
+14 -8
View File
@@ -5,22 +5,28 @@ make all
```
### Bugs and (Mis)features:
The current status of this entry is:
```
STATUS: uses gets() - change to fgets() if possible
```
For more detailed information see [1996 huffman in bugs.md](/bugs.md#1996-huffman).
## To use:
```sh
echo 'Huffman Decoding' | ./huffman
```
NOTE: this program uses `gets()` so you will likely get a warning when compiling
and/or running on modern systems.
### Try:
```sh
echo 'seeing or feeling is believing' | ./huffman
echo 'CC OR NOT CC' | ./huffman
echo 'CC OR NOT CC' | ./huffman | ./huffman
./try.sh
```
@@ -34,7 +40,7 @@ And for a misleading hint, consider who won! :-)
And if you really can't see what is going on, here is an extra spoiler:
```sh
./huffman < huffman.c
./huffman < huffman.c 2>/dev/null
```
This entry was very well received at the IOCCC BOF.
@@ -46,7 +52,7 @@ This filter program is really not obfuscated code. It compiles cleanly
with an ANSI C compiler and comes with user documentation that even a
blind person could read.
The program is a bidirectional filter with the output of the program\
The program is a bidirectional filter with the output of the program
suitable for its input. The output of this program, when used as input,
undoes the original program filtering.
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
make all >/dev/null || exit 1
echo "$ echo 'seeing or feeling is believing' | ./huffman" 1>&2
echo 'seeing or feeling is believing' | ./huffman 2>/dev/null
echo "$ echo 'CC OR NOT CC' | ./huffman" 1>&2
echo 'CC OR NOT CC' | ./huffman 2>/dev/null
echo "$ $ echo 'CC OR NOT CC' | ./huffman | ./huffman" 1>&2
echo 'CC OR NOT CC' | ./huffman 2>/dev/null | ./huffman 2>/dev/null
+8 -2
View File
@@ -23,7 +23,7 @@ For more information try:
## Judges' remarks:
For a good noop try:
For a good no-op try:
```sh
gzip -c < rcm.c | ./rcm
@@ -39,22 +39,27 @@ similar unimportant fluff, this program is a fully compliant
`gzip` compressed file on standard input, and it will write the fully
uncompressed original file to standard output.
### ObJustifications for this entry:
#### The Design Trade-off Argument:
"The 184 characters worth of defines in the build file have been
carefully offset by 184 redundant and unnecessary '`{`', '`}`', and '`;`'
characters in the source file."
#### The Design Review Argument:
"Using only 216 characters out of a maximum of 256, the build file
meets and actually exceeds specification."
#### The Program Metrics Argument:
"The program source is less than 3,100 characters in length and uncompresses file
"The program source is less than 3,100 characters in length and uncompresses the
file
[emacs-19.34b.tar.gz](https://ftp.gnu.org/old-gnu/emacs/emacs-19.34b.tar.gz) in
about 130 seconds on my HP 9000/735. The now obsolete source file `inflate.c'
from the GNU gzip source tree is 31,613 characters in length and uncompresses
@@ -67,6 +72,7 @@ the emacs distribution file in slightly under 25 seconds. Thus:
which represents a better than 530% improvement in the ratio of
source file size to execution time."
#### The Whining Programmer's Argument:
"The inflate algorithm requires that over 400 characters worth
+20 -15
View File
@@ -23,8 +23,8 @@ To find the day that Easter falls on in the current year:
## Judges' remarks:
Look at the source. There is something very odd going on here.\
Where does the real code come from if everything is a C pre-processor\
Look at the source. There is something very odd going on here.
Where does the real code come from if everything is a C pre-processor
statement?
Clearly this is either the Best Use or the Worst Abuse of the
@@ -39,10 +39,12 @@ This program is an implementation of an algorithm that calculates
the date of the Sunday following the first full moon after the
spring equinox. (Also known as "Easter", defined this way by the
Nicaean Concilium in 325 Anno Domini.) The algorithm is attributed
to the famous mathematician Carl Friedrich Gauss ["Meyers Handbuch
ueber das Weltall", Meyer, 5th Edition, 1973, p149] and is suitable
for anni domini within the Gregorian Calendar, that is, from 1582 AD
to 2199 AD:
to the famous mathematician [Carl Friedrich
Gauss](https://en.wikipedia.org/wiki/Carl_Friedrich_Gauss) ["Meyers Handbuch
ueber das Weltall" 'Handbook About Space', Meyer, 5th Edition, 1973, p149] and is suitable
for anni domini within the [Gregorian
Calendar](https://en.wikipedia.org/wiki/Gregorian_calendar), that is, from ad 1582
to ad 2199:
```
Let J be the year.
@@ -70,18 +72,18 @@ with the following exceptions:
```
April 26 must always be changed to April 19
April 25 must be changed to April 18 if d is 28 and a greater than 10
April 25 must be changed to April 18 if d is 28 and a is greater than 10
```
### Example:
```
J = 1962, M = 24, N = 5
a = J % 19 = 5
b = J % 4 = 2
c = J % 7 = 2
d = 119 % 30 = 29
e = 191 % 7 = 2
a = J % 19 == 5
b = J % 4 == 2
c = J % 7 == 2
d = 119 % 30 == 29
e = 191 % 7 == 2
```
March 53 is invalid, so the result is April 22 1962.
@@ -101,7 +103,7 @@ Nobody can learn that by heart so I gently remind the reader by
defining a macro that expresses this clearly (line 25). This goes up
to the definition of a translation unit. Unfortunately, due to the
IOCCC's size restrictions, I had to abbreviate some syntactic
elements. "ae" actually reads "assignment expression". I had to stop
elements. `ae` actually reads "assignment expression". I had to stop
at some arbitrary point, so don't waste your time trying to find out
how preprocessing tokens form type qualifier lists, cast expressions
or direct abstract declarators. Assuming the reader knows about
@@ -109,9 +111,10 @@ these easy to remember language elements is justified in my opinion.
### The moral:
\
Try to be as precise as can be and no one will comprehend what you mean.
#### The formula:
@@ -119,6 +122,7 @@ Try to be as precise as can be and no one will comprehend what you mean.
comprehension = 1/(2**precision)
```
#### The interpretation:
"Say nothing and everybody will understand."
@@ -130,7 +134,8 @@ This leads to an error due to the redefinition of main. The `-I` option makes
sure the working /usr/include/errno.h is found first, which shouldn't cause any
problems on other systems.
### Usage
### Usage:
The program is run without arguments. It prints all dates in order.
+22 -16
View File
@@ -25,7 +25,7 @@ The program accepts up to 4 parameters:
### Try:
```sh
./schweikh2 15 1 0 0/0
./try.sh
```
What happens if you pass only three parameters like the below?
@@ -40,15 +40,20 @@ The author also suggests:
while :; do grep -v '#' schweikh2.c; done
```
(and we do too) which works with `sh`, `bash`, `ksh` and `zsh` as well.
(and we do too) which works with `sh`, `bash`, `ksh` and `zsh` as well. Press
ctrl-c to stop it. Observe how the [try.sh](try.sh) script does this a number of
times.
## Judges' remarks:
The original program, with only slight obfuscations, may be found
in `hunni.c`. The perl script, obfuscates it appropriately:
in [hunni.c](hunni.c). The perl script, [hunni.pl](hunni.pl), obfuscates it
appropriately. Try:
```sh
less hunni.c
perl ./hunni.pl < hunni.c
```
@@ -60,6 +65,7 @@ This entry was another crowd pleaser at the IOCCC BOF.
Note: the source must be viewed with tabstop 8. To appreciate the
beauty have your eyes half closed.
### Why I think this program is obfuscated:
C is a free format language. It is therefore a question of style how
@@ -69,16 +75,16 @@ I put spaces around operators, after opening braces and before closing
braces. I have generalized this rule by putting whitespace after *any*
non-white space character (with the exception of preprocessor directives).
There are no recognizable keywords anymore. There are no recognizable
string literals any more. The main function is invisible. All operators
longer than one character have gone. They have been replaced by macro
string literals any more. The `main()` function is invisible. All operators
longer than one character are gone. They have been replaced by macro
calls with quite a number of arguments. The keys are the token pasting
and stringizing macros e and O. The "arcane rules of token pasting"
[K&R2] are used up to three levels, `H(O,r)R(O,r)` (!) which is needed to make
one 8-character token from 8 characters ('unsigned'). BTW, C has no 9 or
and stringizing macros `e` and `O`. The "arcane rules of token pasting"
[K&R2] are used up to three levels: `H(O,r)R(O,r)` (!) which is needed to make
one 8-character token from 8 characters (`unsigned`). BTW, C has no 9 or
more character reserved words, so a fourth level is only required if
you intend to generate object names from 9 or more components. The final
round even swaps the tokens, so all keywords must be spelled backwards
(sort of, can you spot printf in the P macro?).
(sort of, can you spot `printf` in the `P` macro?).
Try to indent the source. The unbalanced parentheses confuse Solaris'
indent to the max (although the result does compile):
@@ -112,18 +118,18 @@ divided by their greatest common divisor.
The program accepts up to 4 parameters:
1. The number of operators in the expression [default: 9]
2. The value of the first operand [1]
3. The (possibly negative) increment to the next operand [1]
4. The goal value or 0/0 [42]
1. The number of operators in the expression [default: 9].
2. The value of the first operand [1].
3. The (possibly negative) increment to the next operand [1].
4. The goal value or 0/0 [42].
On ANSI/ISO C conformant systems (where long is at least 32 bits)
On ANSI/ISO C conformant systems (where `long` is at least 32 bits)
overflow will occur in the default case (first operand 1, increment 1)
only for more than 11 operators. Because a bit mask is used that needs
twice the number of operands in bits (plus a sentinel value) on those
systems the first parameter must not exceed 15.
If long is at least 64 bits overflow will occur for more than 19
If `long` is at least 64 bits overflow will occur for more than 19
operators but you will probably wait quite some time for every of the
`4^19 = 274,877,906,944` combinations to be evaluated... While I'm at it,
on a 50 MHz SPARC, `4^11` expressions are evaluated in about 3 cpu
@@ -142,7 +148,7 @@ minutes (`gcc -O3`).
### Miscellaneous
The diamond pattern can be continued without a break.\
The diamond pattern can be continued without a break.
For a nice printout try this on your Bourne compatible shell:
```sh
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
make all >/dev/null || exit 1
read -r -n 1 -p "Press any key to to run ./schweikh2: " 1>&2
./schweikh2
echo >&2
read -r -n 1 -p "Press any key to run: ./schweikh2 15 1 0 0/0 | head -n 15: " 1>&2
./schweikh2 15 1 0 0/0 | head -n 15
echo >&2
read -r -n 1 -p "Press any key one more time: " 1>&2
i=0
while ((i++<15)); do
grep -v '#' schweikh2.c
done
+30 -27
View File
@@ -47,19 +47,19 @@ NOTE: On some systems such as SunOS, one may need to compile with:
### Why I think my entry is obfuscated
There are some layout obfuscations that hinder readability, like
some (but not all) one character tokens in column 1. Includes,
defines and declarations of data and functions appear intermixed.
iso646.h is even included in the middle of an expression, how
disgusting. Besides, requiring iso646.h will render the program
some (but not all) one character tokens in column 1. `#include`s,
`#define`s and declarations of data and functions appear intermixed.
`iso646.h` is even included in the middle of an expression, how
disgusting. Besides, requiring `iso646.h` will render the program
uncompilable on many systems that have not yet incorporated
Amendment One to The Standard. If you, dear reader, suffer from
this disease, just read iso646.h.
this disease, just read `iso646.h`.
There are no `if' statements. They have been replaced by
"switch () case 1:" or "switch () case 0:" etc. At least one
switch has a declaration after the opening brace, booh!
Identifiers are named after random programming languages, Basic,
Cobol, F77, awk etc.
`switch () case 1:` or `switch () case 0:` etc. At least one
`switch` has a declaration after the opening brace, booh!
Identifiers are named after random programming languages, BASIC (as `Basic`),
COBOL, F77, awk etc.
You have to select maximum ANSI C conformance of your
compiler. The source fails to compile under a C++ compiler due to
@@ -94,15 +94,15 @@ The source fails to compile on obsolete systems with obsolete
memory models due to the identifier `far` (to be honest: this is
untested :-) ).
Does your indent cope with backslash/newline pairs inbetween
keywords like in "re\<newline>turn"? Solaris' indent inserts spaces\
and thereby renders the source uncompilable...
Does your indent cope with backslash/newline pairs in between keywords like in
`re\turn` where the `re\` is at the end of a line? ? Solaris' indent inserts
spaces and thereby renders the source uncompilable...
The indented source will exhibit different semantics when indenting
changes the number of lines (due to using the `__LINE__` macro in an
expression).
And what about sizeof `__TIME__`? This one's for the philosophers\
And what about `sizeof __TIME__`? This one's for the philosophers
and physicists among us programmers. What is it? `sizeof (char *)`? -- no.
`strlen ("hh:mm:ss")`? -- no. It's the same as `sizeof __DATE__ -
sizeof "no"` :-)
@@ -114,22 +114,22 @@ possible execution paths.
### What this program does
This program tests your operating system's allocation honesty. It
forks a child that will allocate as much as possible with byte
forks a child that will allocate as much memory as possible with byte
granularity and then write to every 1024th byte, at the same time
writing a status report on stdout. This way each page of the
writing a status report on `stdout`. This way each page of the
allocated virtual memory will eventually be referenced. Without
any arguments, malloc() will be used to allocate memory. If the
first arg starts with c, calloc() will be used instead.
any arguments, `malloc(3)` will be used to allocate memory. If the
first arg starts with `c`, `calloc(3)` will be used instead.
I distinguish three different behaviours:
1. OS without memory overcommit: malloc does not lie -- you can use all memory
1. OS without memory overcommit: `malloc(3)` does not lie -- you can use all memory
the OS granted to you.
2. OS with memory overcommit: malloc lies -- any program may get killed at
2. OS with memory overcommit: `malloc(3)` lies -- any program may get killed at
random when the OS can not acquire a free page.
3. OS with pseudo memory overcommit: malloc lies -- The OS puts processes to
3. OS with pseudo memory overcommit: `malloc(3)` lies -- The OS puts processes to
sleep for which it can not acquire a free page. Because other processes are also
affected this way, the system slows down and quickly becomes totally unusable
(also known as "thrashing"). Because more and more processes wait for memory
@@ -137,31 +137,34 @@ returned by other exiting processes the system eventually enters a deadlock
situation and effectively halts.
I had the pleasure and pain to find all three behaviours on the
platforms I use regularly. What follows are the outputs for
platforms I use regularly.
The file [schweikh3.info](schweikh3.info) has output for
Solaris, FreeBSD and Linux. The Linux case is interesting in that
the behaviour changes when calloc is used instead of malloc.
the behaviour changes when `calloc(3)` is used instead of `malloc(3)`.
For FreeBSD, the last two lines are not messages stemming from
my program but issued by the syslog daemon.
### Implementation remarks
How can we distinguish the three different OS types from the
table above?
Obviously, type 1), no overcommit, is easy.
Obviously, type (1), no overcommit, is easy.
For type 2), random kill, we need to fork a child that can be killed
For type (2), random kill, we need to fork a child that can be killed
and whose exit status the parent collects and decodes. Here's
where POSIX enters the scene.
Type 3), thrashing, was the hardest part. The first attempt was to
Type (3), thrashing, was the hardest part. The first attempt was to
measure the elapsed processor time it takes to write a single byte
(using `clock()`). If a certain threshold is reached I assume the
system is thrashing. When thrashing, however, the process does not
consume processor time in a noticeable amount any longer and I lose.
So I switched to measuring wall clock time using `time()`. On the one
So I switched to measuring wall clock time using `time(3)`. On the one
system that I observe thrashing (Linux) this works (although the
value returned by time seems to 'hang' sometimes when the OS thrashes.
value returned by `time(3)` seems to 'hang' sometimes when the OS thrashes.
Exceeding a threshold of 5 seconds may be detected only after half a
minute or so.
+5 -5
View File
@@ -1,6 +1,6 @@
***** SOLARIS 2.5 (sparc):
% prog
% schweikh3
Trying to malloc 2048M+0K+0 bytes..nope
Trying to malloc 1024M+0K+0 bytes..nope
Trying to malloc 512M+0K+0 bytes..nope
@@ -41,7 +41,7 @@
***** FreeBSD 2.1 (i386):
% prog
% schweikh3
Trying to malloc 2048M+0K+0 bytes..nope
Trying to malloc 1024M+0K+0 bytes..nope
Trying to malloc 512M+0K+0 bytes..nope
@@ -82,7 +82,7 @@
Nov 24 18:11:56 /kernel: swap_pager: out of space
Nov 24 18:11:57 /kernel: Process 5 killed by vm_fault -- out of swap
% prog c
% schweikh3 c
Trying to calloc 2048M+0K+0 bytes..nope
Trying to calloc 1024M+0K+0 bytes..nope
Trying to calloc 512M+0K+0 bytes..nope
@@ -96,7 +96,7 @@
***** Linux 1.2.13 (i386):
% prog
% schweikh3
Trying to malloc 2048M+0K+0 bytes..nope
Trying to malloc 1024M+0K+0 bytes..nope
Trying to malloc 512M+0K+0 bytes..nope
@@ -132,7 +132,7 @@
Able to malloc 23M+1023K+1023 bytes
23294 kilo bytes ok malloc lied! Thrashing
% prog c
% schweikh3 c
Trying to calloc 2048M+0K+0 bytes..nope
Trying to calloc 1024M+0K+0 bytes..nope
Trying to calloc 512M+0K+0 bytes..nope
+3 -2
View File
@@ -39,7 +39,8 @@ include ../../var.mk
# Common C compiler warnings to silence
#
CSILENCE= -Wno-char-subscripts -Wno-error -Wno-implicit-function-declaration \
-Wno-int-to-pointer-cast -Wno-empty-body -Wno-deprecated-non-prototype
-Wno-int-to-pointer-cast -Wno-empty-body -Wno-deprecated-non-prototype\
-Wno-implicit-int
# Common C compiler warning flags
#
@@ -109,7 +110,7 @@ ENTRY= westley
PROG= ${ENTRY}
#
OBJ= ${PROG}.o
DATA= clock1 clock2 clock3
DATA= clock1.sh clock2.sh clock3.sh
TARGET= ${PROG}
#
ALT_OBJ= westley.alt.o
+27 -30
View File
@@ -4,51 +4,46 @@
make all
```
There is another version which is the original entry. See [alternate
version](#alternate-code) for details as to how to use and why it was made the
alt version.
## To use:
```sh
sh ./clock1
./clock1.sh
./clock2.sh
./clock3.sh
```
NOTE: the original version had a display problem in modern systems which
somewhat affected the usability of the program. See the Alternate code section
for details on the original version.
### Try:
```sh
sh ./clock2
```
And for a good time, try:
```sh
sh ./clock3
./try.sh
```
## Alternate code:
An alternate version of this entry, [westley.alt.c](westley.alt.c), is provided.
This version is the original code and does not contain the above mentioned
fixes.
The original version had a display problem in modern systems which somewhat
affected the usability of the program. This alternate code, the original, is
provided, to show the differences.
### Alternate build:
To compile this alternate version:
```sh
make alt
```
To use it with the scripts try:
### Alternate try:
```sh
WESTLEY=./westley.alt ./clock1
WESTLEY=./westley.alt ./clock2
WESTLEY=./westley.alt ./clock3
./try.alt.sh
```
@@ -66,7 +61,8 @@ This 1-line program allows various analog ASCII clocks to print out the time;
the ASCII clock is built from the command line arguments, so many different
types of clocks can be generated. Three different scripts are supplied to print
out a grandfather clock, a mantle clock that runs backwards, and a linear-style
clock. (they are `clock1`, `clock2`, and `clock3`)
clock. (they are [clock1.sh](clock1.sh), [clock2.sh](clock2.sh), and
[clock3.sh](clock3.sh))
The program makes the following (possibly non-portable) assumptions:
@@ -74,8 +70,8 @@ The program makes the following (possibly non-portable) assumptions:
2. `argv[0]` can be written to as if it were a `long *`.
3. The first three elements of the struct * returned by localtime() are seconds,
minutes, hours, and all are ints.
3. The first three elements of the `struct *` returned by `localtime(3)` are
seconds, minutes, hours, and all are `int`s.
4. My sample scripts assume ASCII, though this is not inherent in the code, just
my sample scripts.
@@ -83,6 +79,7 @@ my sample scripts.
These assumptions are pretty reasonable. 2) can be eliminated but makes the code
larger.
The code is simple; the arguments passed are:
```sh
@@ -94,14 +91,14 @@ values, looks up the offsets in `minute_map` and `hour_map`
and writes the `hand_symbol` for each into the `clock_image`
string. This string is then printed.
The for() loop starts by calling `time()` with `argv[0]`, so
the time value (a long) is written into the program name.
The for() control value is `argc`, which starts at `5`, but
the `/=2` statement is executed before the test, so the for()
The `for()` loop starts by calling `time()` with `argv[0]`, so
the time value (a `long`) is written into the program name.
The `for()` control value is `argc`, which starts at `5`, but
the `/=2` statement is executed before the test, so the `for()`
loop is executed twice, with `h=2`, then `h=1` (for hour & minute).
The statement of the for() loop takes the hour or minute
field of the struct returned by `localtime()` by casting it
The statement of the `for()` loop takes the hour or minute
field of the struct returned by `localtime(3)` by casting it
to an `int *` and dereferencing element `[h]`. It is slightly
smaller to use the trick `h[(int*)localtime(*m)]` instead of
`((int*)localtime(*m))[h]`.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
make everything 1>/dev/null || exit 1
echo "Showing alt grandfather clock:" 1>&2
WESTLEY=./westley.alt ./clock1.sh
read -r -n 1 -p "Press any key to continue: " 1>&2
echo "Showing alt mantle clock that runs backwards:" 1>&2
WESTLEY=./westley.alt ./clock2.sh
read -r -n 1 -p "Press any key to continue: " 1>&2
echo "Showing alt linear style clock:" 1>&2
WESTLEY=./westley.alt ./clock3.sh
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
make everything 1>/dev/null || exit 1
echo "Showing grandfather clock:" 1>&2
WESTLEY=./westley ./clock1.sh
read -r -n 1 -p "Press any key to continue: " 1>&2
echo "Showing mantle clock that runs backwards:" 1>&2
WESTLEY=./westley ./clock2.sh
read -r -n 1 -p "Press any key to continue: " 1>&2
echo "Showing linear style clock:" 1>&2
WESTLEY=./westley ./clock3.sh
+1 -1
View File
@@ -31,7 +31,7 @@ make
## Judges' remarks:
We were able to write our own program performing the same trick using the (still
We were able to [write our own program](rand.c) performing the same trick using the (still
non-standard, for some reason) library function `memmem()`, but that way it
works too fast regardless of the context length, and it's much less fun.
+41 -36
View File
@@ -1126,29 +1126,6 @@ _before you choose where to shoot_.
When you shoot it will move you to that room so if you end up shooting into a
pit room you will end up dying even though you didn't explicitly move there.
### STATUS: known bug - please help us fix
A (mis)feature is that one must have had all arrows stolen in order to recover
all the arrows from the robber. This means that if you end up shooting an arrow
you can never recover all the arrows from the robber because the count of arrows
stolen can never be high enough. There are a number of ways this might be fixed,
some of which Cody notes:
- If you have zero arrows and you come across the robber you could give them all
back. This is not correct though because if you never had that many arrows you
would end up getting arrows back that you never had in the first place.
- A new variable, an `int`, could be added that keeps track of the number of
arrows you have fired and then if you come across the robber and they took the
number of arrows with the difference of the number fired then you would give
back how many (the difference) the robber stole rather than all the arrows. This
would be the right approach but there are certainly other ways to go about it.
A tip is that the number of arrows stolen is `l` and the number of arrows you
have is `i`. For the alt version that Cody added the starting number of arrows
is in the constant `W`, defaulting to 3.
You are welcome to try and fix this (mis)feature.
## 1994 ldb
@@ -1393,19 +1370,6 @@ We would appreciate anyone who has it or even just knows the name! Thank you.
# 1996
## 1996 august
### STATUS: doesn't work with some compilers - please provide alternative code or fix for more compilers
### Source code: [1996/august/august.c](1996/august/august.c)
### Information: [1996/august/README.md](1996/august/README.md)
[Cody Boone Ferguson](/winners.html#Cody_Boone_Ferguson) fixed a segfault in
this program that prevented it from working in gcc. It is known, however, that
some compilers will compile the code so that it enters an infinite loop (an
example is in macOS).
If you can fix this we welcome it!
## 1996 gandalf
### STATUS: missing or dead link - please provide them
@@ -1418,6 +1382,47 @@ it was instead requiring a login / password.
Do you have an updated link? We welcome your help!
## 1996 huffman
### STATUS: uses gets() - change to fgets() if possible
### Source code: [1996/huffman/huffman.c](1996/huffman/huffman.c)
### Information: [1996/huffman/README.md](1996/huffman/README.md)
The changing to using `fgets(3)` in this entry is a bit more complicated. It can
almost be done except that some of the output of the
[try.sh](1996/huffman/try.sh) is wrong, especially the last one.
This diff almost does it but not quite:
```diff
diff --git i/1996/huffman/huffman.c w/1996/huffman/huffman.c
index a5745bc7f4fa28b834c004f4cf19633e40ad9165..5e5e5334f33f9dbd95c70eddece3189d9bcff5e9 100644
--- i/1996/huffman/huffman.c
+++ w/1996/huffman/huffman.c
@@ -1,15 +1,16 @@
#define x char
#define z else
#define w gets
+#define gets(b) ((b)[0]='\0',(fgets((b), 100, stdin)))
#define r if
#define u int
#define s main
#define v putchar
#define y while
#define t " A?B?K?L?CIF?MSP?E?H?O?R?DJG?NTQ?????U?V?????X???????Z????W??Y??"
- s ( ) { x* c , b[ 5 * 72 ]; u a, e , d [ 9
+ s ( ) { x* c , b[ 5 * 72 ]; u a, e , d [ 9
*9 *9 ] ; y (w ( b) ){ r ( 0 [ b] -7 *
5 ) { c = b ; y ( (* c - 6
* 7 )* * c )c = c+ 1 ; r (( -0 ) [ c ] && w ( b +
8 * 5* 3 ) && w (b +8 *5 * 6) )
{ a = 0; y ( a [ b ]
```
But since it does not for the time being it is advisable to just redirect stderr
to /dev/null (`2>/dev/null`).
## 1996 jonth
### STATUS: INABIAF - please **DO NOT** fix
+65 -13
View File
@@ -1758,9 +1758,16 @@ As in some places it would properly say that you have '1 arrow' or else, if you
have any other number of arrows (including 0), it would say 'arrows', Cody fixed
a place where it always said 'arrows'. A minor fix and not that important.
Cody notes that there is a (mis)feature in the program that might want to be
fixed that he has not had the time to fix yet; see [1991/dodsond2 in
bugs.md](/bugs.md#1994-dodsond2) for more details.
Cody also fixed the problem where one could only get the arrows back from the
robber if the robber stole as many arrows as you ever found rather than that
minus how many you have shot. In other words if you had three arrows and shot
one and found no more you could never get the arrows back from the robber
because you could never lose all three since you spent one. This bug manifested
itself in another way too: once you got the arrows back the counter was not
reset so you could only get the arrows back once even if the robber stole more.
Now the counters are reset. The way this bug was fixed is that there is now a
counter for how many you have found and how many you shot in addition to the two
that already existed, how many you had and how many were stolen.
## [1994/horton](1994/horton/horton.c) ([README.md](1994/horton/README.md))
@@ -1912,9 +1919,12 @@ are created by the entry or the entry decrypts the text or whatever else.
## [1996/august](1996/august/august.c) ([README.md](1996/august/README.md]))
Cody fixed a segfault in this program that prevented it from working right but
he notes that some compilers compile it into an infinite loop (an example where
this happens is macOS).
Cody fixed a segfault in this program that prevented it from working right and
also fixed an infinite loop in the try commands. The problem with the infinite
loop is that the file `august.oc` had to have lines starting with `#` removed
and it was not being done. After this is done with say `sed(1)` (like `sed -i''
'/^#/d' august.oc` which has been added to both the remarks and the try.sh
script as described below) the code can proceed. This problem existed in macOS.
Cody also added the [try.sh](1996/august/try.sh) script that runs all the
commands given in the try section to simplify it as there are quite a lot of
@@ -1924,15 +1934,18 @@ commands.
## [1996/dalbec](1996/dalbec/dalbec.c) ([README.md](1996/dalbec/README.md]))
Cody proposed a fix for this to compile with clang and Landon implemented it
after some discussion. The reason Cody did not do it is because he thought it
was the wrong output but as it happens the try section below was worded a bit
confusingly. He looked at Yusuke's] analysis found
after some discussion (though Cody changed the function name). The reason Cody
did not do it is because he thought it was the wrong output but as it happens
the try section below was worded a bit confusingly. He looked at Yusuke's
analysis found
[here](https://mame-github-io.translate.goog/ioccc-ja-spoilers/1996/dalbec.html?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=en-US&_x_tr_pto=wapp)
but he missed that Yusuke added a '...' after the result which made him think
the fix was wrong. Cody also made the recommended change of the author to make
it so that each number is printed on a line by itself rather than having a long
string of numbers on the same line. This was not put in an alternate version but
perhaps it should be.
the fix was wrong.
Cody also made the recommended change of the author to make it so that each
number is printed on a line by itself rather than having a long string of
numbers on the same line. This was not put in an alternate version but perhaps
it should be.
## [1996/eldby](1996/eldby/eldby.c) ([README.md](1996/eldby/README.md]))
@@ -1951,6 +1964,18 @@ Cody fixed this to compile and work with modern systems. As he loved the
references in the code that could not compile he just commented out as little as
possible to get this to compile.
Cody also added the rather useful [try.sh](1996/gandalf/try.sh) script to
really demonstrate the different ways of running the program ends up showing
either different output or the same output that we briefly pointed out.
BTW: it is perilous to try the patience of
[Gandalf](https://www.glyphweb.com/arda/g/gandalf.html). Go ahead, try it! :-)
## [1996/huffman](1996/huffman/huffman.c) ([README.md](1996/huffman/README.md]))
Cody added the [try.sh](1996/huffman/try.sh) script.
## [1996/jonth](1996/jonth/jonth.c) ([README.md](1996/jonth/README.md]))
@@ -1961,6 +1986,26 @@ the function in the pointer assignment.
NOTE: if there is no X server running this program will still crash.
## [1996/schweikh1](1996/schweikh1/schweikh1.c) ([README.md](1996/schweikh1/README.md]))
The author stated that `-I/usr/include` is needed by gcc in Solaris because
`errno.h` has two identical extern declarations of `errno`. That leads to an
error due to the redefinition of `main` but the `-I` option makes sure the
working `/usr/include/rrno.h` is found first, which shouldn't cause any problems
on other systems (the other file is
`gcc-lib/sparc-sun-solaris2.5/2.7.2/include/errno.h`). Thus Cody added this to
the Makefile despite the fact that very few probably use Solaris nowadays.
## [1996/schweikh2](1996/schweikh2/schweikh2.c) ([README.md](1996/schweikh2/README.md]))
Cody added the [try.sh](1996/schweikh2/try.sh) script with a few commands to try
along with a shorter version of something the author suggested one try (it is
suggested that one try the longer version too but it will run in an infinite
loop so having it in a script is less desired).
## [1996/westley](1996/westley/westley.c) ([README.md](1996/westley/README.md]))
Cody fixed a segfault in this entry as well as it displaying environmental
@@ -1974,6 +2019,13 @@ Note that you should check the [westley.alt.c](1996/westley/westley.alt.c) file
when reading the author's comments. To see how to use the original, see the
README.md file.
Cody also added the two scripts, [try.sh](1996/westley/try.sh) and
[try.alt.sh](1996/westley/try.alt.sh) to show automate showing the different
clocks, both with the fixed version and the original (alt) version.
Also, to fix any potential problem with displaying in GitHub the scripts
provided by the author, Cody added '.sh'.
## [1998/chaos](1998/chaos/chaos.c) ([README.md](1998/chaos/README.md]))