Merge pull request #1132 from xexyl/1989-vanb

This commit is contained in:
Landon Curt Noll authored and GitHub committed 2023-10-20 21:53:28 -07:00
commit c2906990b9
26 files changed
+406 -178

No files matched your search

+2 -2
View File
@@ -62,11 +62,11 @@ CDEFINE=
# Include files that are needed to compile
#
CINCLUDE=
CINCLUDE= -include stdio.h
# Optimization
#
OPT= -O3
OPT=
# Default flags for ANSI C compilation
#
+5 -3
View File
@@ -6,15 +6,17 @@
#define l int
#define C y=v+111;H(x,v)*y++= *x
#define H(a,b)R(a=b+11;a<b+89;a++)
#define s(a)t=scanf("%d",&a)
#define s(a)t=scanf("%2s",a)
char A[100];
l V[1100],u,r[]={-1,-11,-10,-9,1,11,10,9},h[]={11,18,81,88},ih[]={22,27,72,77},
bz,lv=60,*x,*y,m,t;S(d,v,f,a,b)l*v;{l c=0,*n=v+100,bw=d<u-1?a:-9000,w,z,i,zb,q=
3-f;if(d>u){R(w=i=0;i<4;i++)w+=(m=v[h[i]])==f?300:m==q?-300:(t=v[ih[i]])==f?-50
:t==q?50:0;return w;}H(z,0){if(GZ(v,z,f,100)){c++;w= -S(d+1,n,q,-b,-bw);if(w>bw
){zb=z;bw=w;if(w>=b||w>=8003)Y w;}}}if(!c){bz=0;C;Y-S(d+1,n,q,-b,-bw);}bz=zb;Y
d>=u-1?bw+(c<<3):bw;}main(){R(;t<1100;t+=100)R(m=0;m<100;m++)V[t+m]=m<11||m>88
||(m+1)%10<2?3:0;V[44]=V[55]=1;V[45]=V[54]=2;I("Level:");s(u);e(lv>0){do{I("Yo\
u:");s(m);if(t<1)break;}e(!GZ(V,m,2,0)&&m!=99);if(m!=99)lv--;if(lv<15&&u<10)u+=2;I("Wait\n")
||(m+1)%10<2?3:0;V[44]=V[55]=1;V[45]=V[54]=2;x:*A='\0';I("Level:");s(A);if((u
=atoi(A))>10||u<0||!isdigit(*A))goto x;e(lv>0){do{I("You:");s(A);m=atoi(A);*A='\0';
}e(!GZ(V,m,2,0)&&m!=99);if(m!=99)lv--;if(lv<15&&u<10)u+=2;I("Wait\n")
;I("Value:%d\n",S(0,V,1,-9000,9000));I("move: %d\n",(lv-=GZ(V,bz,1,0),bz));}}GZ
(v,z,f,o)l*v;{l*j,q=3-f,g=0,i,h,*k=v+z;if(*k==0)R(i=7;i>=0;i--){j=k+(h=r[i]);e(
*j==q)j+=h;if(*j==f&&j-h!=k){if(!g){g=1;C;}e(j!=k)*((j-=h)+o)=f;}}Y g;}
+5 -3
View File
@@ -7,8 +7,9 @@
#define W if
#define C y=v+111;H(x,v)*y++= *x
#define H(a,b)R(a=b+11;a<b+89;a++)
#define s(a)t=scanf("%d",&a)
#define s(a)t=scanf("%2s",&a)
#define U Z I
char A[100];
#define Z I("123\
45678\n");H(x,V){putchar(".XO"[*x]);W((x-V)%10==8){x+=2;I("%d\n",(x-V)/10-1);}}
l V[1600],u,r[]={-1,-11,-10,-9,1,11,10,9},h[]={11,18,81,88},ih[]={22,27,72,77},
@@ -17,8 +18,9 @@ bz,lv=60,*x,*y,m,t;S(d,v,f,_,a,b)l*v;{l c=0,*n=v+100,j=d<u-1?a:-9000,w,z,i,g,q=
t==q?50:0;Y w;}H(z,0){W(E(v,z,f,100)){c++;w= -S(d+1,n,q,0,-b,-j);W(w>j){g=bz=z;
j=w;W(w>=b||w>=8003)Y w;}}}W(!c){g=0;W(_){H(x,v)c+= *x==f?1:*x==3-f?-1:0;Y c>0?
8000+c:c-8000;}C;j= -S(d+1,n,q,1,-b,-j);}bz=g;Y d>=u-1?j+(c<<3):j;}main(){R(;t<
1600;t+=100)R(m=0;m<100;m++)V[t+m]=m<11||m>88||(m+1)%10<2?3:0;I("Level:");V[44]
=V[55]=1;V[45]=V[54]=2;s(u);e(lv>0){Z do{I("You:");s(m);if(t<1)break;}e(!E(V,m,2,0)&&m!=99);
1600;t+=100)R(m=0;m<100;m++)V[t+m]=m<11||m>88||(m+1)%10<2?3:0;x:I("Level:");V[44]
=V[55]=1;V[45]=V[54]=2;s(A);if(((u=atoi(A))>10)||u<0||!isdigit(*A))goto x;e(lv>0){Z
do{I("You:");s(A);m=atoi(A);*A='\0';}e(!E(V,m,2,0)&&m!=99);
W(m!=99)lv--;W(lv<15&&u<10)u+=2;U("Wait\n");I("Value:%d\n",S(0,V,1,0,-9000,9000
));I("move: %d\n",(lv-=E(V,bz,1,0),bz));}}E(v,z,f,o)l*v;{l*j,q=3-f,g=0,i,w,*k=v
+z;W(*k==0)R(i=7;i>=0;i--){j=k+(w=r[i]);e(*j==q)j+=w;W(*j==f&&j-w!=k){W(!g){g=1
+3 -1
View File
@@ -140,10 +140,12 @@ alt: data ${ALT_TARGET}
@${TRUE}
${PROG}.alt: ${PROG}.alt.c
@echo "NOTE: The original source might not compile using modern compilers."
@echo NOTE: this compilation results in running the program itself.
${RM} -f $@
${CP} jar.1.alt.sh $@
${CHMOD} +x $@
@echo NOTE: We will now simulate: ${CC} -c -o /dev/tty jar.1.alt.c
${CC} -c -o /dev/stdout jar.1.alt.c 2>/dev/null | ${STRINGS}
# data files
#
+15 -6
View File
@@ -9,36 +9,45 @@ Finland
## To build:
NOTE: this will run the program itself.
```sh
make clobber all
```
There is an alternate version with a slight difference that you may wish to try.
See [Alternate code](#alternate-code) below.
## To run:
NOTE: this will run the program itself:
```sh
make clobber all
```
### Alternate code:
One may try:
This code, which prints something slightly different, is provided as well.
```
./jar.1.sh
```
#### To build:
Or for the original $xurce might not compile using modern compilers, try:
NOTE: this will run the program itself.
```sh
make clobber alt
```
or even:
#### To run:
Alternatively, you can run it directly:
```sh
./jar.1.alt.sh
```
## Judges' remarks:
On many systems the compiler will not allow you to send the object file to
+8 -1
View File
@@ -4,5 +4,12 @@
# run/compile it
rm -f jar.1.alt.o
cc jar.1.alt.c -c
cat jar.1.alt.o | strings
# we do it this way to prevent ShellCheck from whining about useless use of cat,
# a most ill-famed warning. Why is it ill-famed? Because there is no such thing
# as a useless cat! In fact, the fact cats exist is proof that the Earth is NOT
# flat: if it was flat they would have pushed everything off it by now! :-) And
# besides that, they provide hours and hours, years and years even, of joy and
# companionship to ailurophiles and, contrary to popular belief, they most
# certainly do have personalities and they can be very sociable too!
strings < jar.1.alt.o
rm -f jar.1.alt.o
+8 -1
View File
@@ -4,5 +4,12 @@
# run/compile it
rm -f jar.1.o
cc jar.1.c -c
cat jar.1.o | strings
# we do it this way to prevent ShellCheck from whining about useless use of cat,
# a most ill-famed warning. Why is it ill-famed? Because there is no such thing
# as a useless cat! In fact, the fact cats exist is proof that the Earth is NOT
# flat: if it was flat they would have pushed everything off it by now! :-) And
# besides that, they provide hours and hours, years and years even, of joy and
# companionship to ailurophiles and, contrary to popular belief, they most
# certainly do have personalities and they can be very sociable too!
strings < jar.1.o
rm -f jar.1.o
+3 -2
View File
@@ -39,7 +39,7 @@ include ../../var.mk
# Common C compiler warnings to silence
#
CSILENCE= -Wno-implicit-function-declaration -Wno-missing-braces -Wno-parentheses \
-Wno-deprecated-non-prototype -Wno-pedantic -Wno-strict-prototypes
-Wno-deprecated-non-prototype -Wno-pedantic -Wno-strict-prototypes -Wno-implicit-int
# Common C compiler warning flags
#
@@ -130,8 +130,9 @@ all: data ${TARGET}
sandwich supernova deep_magic magic charon pluto
${PROG}: ${PROG}.c
@echo NOTE: invalid input will cause this entry to dump core.
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
@echo
@echo NOTE: invalid input will cause this entry to dump core. See README.md for details.
# alternative executable
#
+38 -20
View File
@@ -19,13 +19,31 @@ make all
```sh
./jar.2
[enter some lisp]
./jar.2 < some_lisp_file
```
NOTE: this entry will likely segfault on invalid input.
## Try:
```sh
./try.me.sh
cat chocolate_cake.lisp ; ./jar.2 < chocolate_cake.lisp
./try.me.sh chocolate_cake.lisp
./try.me.sh try.me.txt
```
## Judges' remarks:
This is the most useful program entered this year. It is a
This is the most useful program submitted this year. It is a
rather large subset of lisp. It has no error recovery, and
performs rather poorly in a number of cases. Even so, placing
all this functionality in such a small, densely packed program,
@@ -35,7 +53,7 @@ is impressive enough to win the Best of show award.
## Author's remarks:
This program implements a Lisp interpreter in 1465 bytes of source.
Some sophisticated features supported, eg. functionals and recursion.\
Some sophisticated features supported, e.g. functionals and recursion.
The special-forms/functions/variables implemented are:
- \+
@@ -61,24 +79,24 @@ prints out the return values. End execution by typing an end-of-file
character.
```lisp
(+ 2.5 3.1)
(defun fib (n)
(if (< n 2)
1
(+ (fib (- n 2)) (fib (- n 1)))))
(fib 10)
(defun ! (x) (if (equal x 0) 1 (* x (! (- x 1)))))
(! 7)
(defun fn1 (fn) (+ (fn 1 2) (fn 3 4)))
(defun fn2 (a b) (+ a b))
(fn1 (function +))
(fn1 (function fn2))
(fn1 (function (lambda (z1 z2) (+ z1 z2))))
(quote a)
(cons (quote (a b)) (quote (c d e)))
(cons (quote (f)) ())
(car (quote (a b c)))
(cdr (cdr (quote (g h i))))
(+ 2.5 3.1)
(defun fib (n)
(if (< n 2)
1
(+ (fib (- n 2)) (fib (- n 1)))))
(fib 10)
(defun ! (x) (if (equal x 0) 1 (* x (! (- x 1)))))
(! 7)
(defun fn1 (fn) (+ (fn 1 2) (fn 3 4)))
(defun fn2 (a b) (+ a b))
(fn1 (function +))
(fn1 (function fn2))
(fn1 (function (lambda (z1 z2) (+ z1 z2))))
(quote a)
(cons (quote (a b)) (quote (c d e)))
(cons (quote (f)) ())
(car (quote (a b c)))
(cdr (cdr (quote (g h i))))
```
+8
View File
@@ -0,0 +1,8 @@
(quote ......................)
(quote ||||||||||||||||||||||)
(quote [[[--hexa-layered--]]])
(quote [[[----layered-----]]])
(quote [[[---chocolate----]]])
(quote [[[-----fudge------]]])
(quote [[[-----cake-------]]])
(quote [[[[[[[[[[]]]]]]]]]]]])
+5
View File
@@ -0,0 +1,5 @@
(defun fib (n)
(if (< n 2)
1
(+ (fib (- n 2)) (fib (- n 1)))))
(fib 10)
+2
View File
@@ -1,4 +1,6 @@
#include <stdio.h>
#define d define
#define a include
#include <string.h>
#include <ctype.h>
#define p char*
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
#
# demo for 1989/jar.2 - run entry with one or more files
make all || exit 1
if [[ "$#" -lt 1 ]]; then
FILES="try.me.txt fib.lisp chocolate_cake.lisp"
else
FILES="$*"
fi
for f in $FILES; do
if [[ -e "$f" && -r "$f" ]]; then
./jar.2 < "$f"
fi
done
+18
View File
@@ -0,0 +1,18 @@
(+ 2.5 3.1)
(defun fib (n)
(if (< n 2)
1
(+ (fib (- n 2)) (fib (- n 1)))))
(fib 10)
(defun ! (x) (if (equal x 0) 1 (* x (! (- x 1)))))
(! 7)
(defun fn1 (fn) (+ (fn 1 2) (fn 3 4)))
(defun fn2 (a b) (+ a b))
(fn1 (function +))
(fn1 (function fn2))
(fn1 (function (lambda (z1 z2) (+ z1 z2))))
(quote a)
(cons (quote (a b)) (quote (c d e)))
(cons (quote (f)) ())
(car (quote (a b c)))
(cdr (cdr (quote (g h i))))
+1
View File
@@ -1,3 +1,4 @@
paul
paul.alt
paul.orig
prog.orig
+2 -2
View File
@@ -114,8 +114,8 @@ OBJ= ${PROG}.o
DATA=
TARGET= ${PROG}
#
ALT_OBJ=
ALT_TARGET=
ALT_OBJ= ${PROG}.alt.o
ALT_TARGET= ${PROG}.alt
#################
+71 -46
View File
@@ -1,10 +1,6 @@
# Most complex algorithm
Paul E. Black\
CIRRUS LOGIC, Inc.\
1463 Centre Pointe Dr.\
Milpitas, CA\
95035\
US
## To build:
@@ -13,6 +9,8 @@ US
make all
```
There is an alternate version with a trace routine that the author had commented
out. See [alternate code](#alternate-code) below for more details.
## Try:
@@ -20,17 +18,43 @@ make all
./paul
```
### Alternate code:
This version was described by the author like:
> I could have squeezed the program under 1024 bytes without the
trace subroutine, but I felt it was important for understanding
the program. Besides it is fun to watch the tape zooming back
and forth as the program runs. A much better debugger or trace
could easily be added.
#### To build:
```sh
make alt
```
#### To use:
```sh
./paul.alt
```
## Judges' remarks:
The original source contained a long line which caused many
mailers to barf. The original file may be re-constructed by
removing the trailing "\" on line 12 and joining lines 12 and
13 together without a space.
The author's comments is a detailed program explanation and spoiler. If you
want a real challenge, don't read any further and try to understand the program
via the source.
WHAT FOLLOWS IS A DETAILED PROGRAM EXPLANATION AND SPOILER.
IF YOU WANT A REAL CHALLENGE, DON'T READ ANY FURTHER AND TRY
TO UNDERSTAND THE PROGRAM VIA THE SOURCE.
### Historical note:
The original source contained a long line which caused many mailers to barf.
The original file may be re-constructed by removing the trailing `\` on line 12
and joining lines 12 and 13 together without a space.
However as this is no longer a problem the trailing `\` has been restored in all
versions, both the original and the fixed for modern systems version.
## Author's remarks:
@@ -43,69 +67,70 @@ natural to write incredibly obscure Turing programs.)
If the program is invoked with an operand, the operand is used
as the Turing program. It includes a "trace" facility,
subroutine r (commented out for obscurity), to help write and
subroutine `r` (commented out for obscurity), to help write and
debug Turing programs. Just the thing for some fun in a Theory
of Computation class.
The Turing machine tape is represented as a doubly linked list
of pointers. The forward and backward links are XOR'd together
of pointers. The forward and backward links are `XOR`ed together
and stored in one pointer. If we always keep one of the links
on hand, we can recover the other link at any time. The
variable q is the scan head (and a pointer at some tape cell),
and p is a "previous" link. The state of the tape is stored in
variable `q` is the scan head (and a pointer at some tape cell),
and `p` is a "previous" link. The state of the tape is stored in
the low order bit of the pointer. Since we always allocate an
even number of bytes, the low order bit carries no information
(see portability below.) Memory representing a tape cell is
(see [portability](#portability) below.) Memory representing a tape cell is
allocated when the cell is first scanned. Thus the simulation
begins with a tape effectively the size of virtual memory set
to all zeros. Since a header can be added to any Turing
program to write initial data and position the scan head, this
is little loss of generality.
The simulated Turing machine has a single tape with either an 1
or a 0 in each cell. The Turing machine language format is a
The simulated Turing machine has a single tape with either a `1`
or a `0` in each cell. The Turing machine language format is a
string of three bytes. The first byte is the current state.
The second byte is the next state. (The last bit of states is
ignored, e.g., B and C are the same state, in an attempt to be
ignored, i.e., `B` and `C` are the same state, in an attempt to be
able to have interesting words in the program.) The third byte
is composed of bits. Bit 1 (2&byte) is the symbol scanned,
is composed of bits. Bit `1` (`2&byte`) is the symbol scanned,
i.e. an instruction is selected for state and for a match with
the symbol under the scan head. Bit 2 (4&byte) is the new
symbol to be written to the cell. Bit 3 (8&byte) is the
direction to move the scan head: 0 for left and 1 for right.
If bit 4 (16&byte) is true, the next character is sent to
stdout. (I added this feature so programs could print
the symbol under the scan head. Bit `2` (`4&byte`) is the new
symbol to be written to the cell. Bit `3` (`8&byte`) is the
direction to move the scan head: `0` for left and `1` for right.
If bit `4` (`16&byte`) is true, the next character is sent to
`stdout`. (I added this feature so programs could print
results.)
The Turing machine has next state `j` when it begins. The
cycle is 1) exit if the state is `x`, 2) find the next
cycle is (1) exit if the state is `x`, (2) find the next
instruction (given the state and the character under the scan
head). [The program string is searched forward for the next
head). (The program string is searched forward for the next
matching instruction. If the end of the string is reached, the
search begins again at the first of the string. Thus states
can be used as local labels in different places.] 3) change to
the next state, 4) print a character if indicated, 5) write the
tape symbol, and 6) move the scan head. The cycle then repeats
can be used as local labels in different places.) (3) change to
the next state, (4) print a character if indicated, (5) write the
tape symbol, and (6) move the scan head. The cycle then repeats
with step 1. A call to the trace routine is just before step
2, but is commented out.
The following ROT13'ed text is a quick outline of the actual
Turing program:
### Quick outline of the Turing program:
Urer vf n dhvpx bhgyvar bs gur Ghevat cebtenz: gur
cerivbhf naq pheerag Svobanppv ahzoref ner xrcg va onfr
1 sbez jvgu gur pheerag ba gur evtug. Gur svefg guerr
fgrcf frg hc gur svefg gjb ahzoref, 1 naq 1. Gura
[ortvaavat jvgu "@ ("] n znexre bs VVV vf perngrq naq
gur pheerag ahzore vf pbcvrq gb gur evtug bs gur
znexre. Gura [ortvaavat jvgu "BI "] gur ahzore vf
pbairegrq gb ovanel ol ercrngrq qvivqvat ol 2 yrnivat V
sbe erznvaqre 1, naq VV sbe erznvaqre 0. Arkg
[ortvaavat jvgu "JI "] gur ovanel ercerfragngvba vf
cevagrq naq vgf flzobyf naq gur znexre ner renfrq.
Svanyyl [ortvaavat jvgu "RRa"] gur gjb ahzoref ner
nqqrq naq gur pheerag ahzore pbcvrq gb gur yrsg gb
orpbzr gur cerivbhf. Gura gur plpyr ercrngf.
The previous and current Fibonacci numbers are kept in base
1 form with the current on the right. The first three
steps set up the first two numbers, `1` and `1`. Then
[beginning with `@ (`] a marker of `III` is created and
the current number is copied to the right of the
marker. Then (beginning with `OV `) the number is
converted to binary by repeatedly dividing by 2 leaving I
for remainder `1`, and II for remainder `0`. Next
(beginning with `WV `) the binary representation is
printed and its symbols and the marker are erased.
Finally (beginning with `EEn`) the two numbers are
added and the current number copied to the left to
become the previous. Then the cycle repeats.
### Portability
The program requires that the lowest bit of a pointer to be 0.
+35
View File
@@ -0,0 +1,35 @@
#include <stdio.h>
#define f long
#define v (void)printf(
#define x ),exit(1);
#define y ){if(n)c=z(n,u),u=n,n=c;o[i]=n?'0'+(1&*n):'0';}
#define z(a,b) (f*)(~1&*a^(f)b)
#define k(l) if(!(l=(f*)malloc(sizeof(l))))v 23+m x if(1&(f)l)v 39+m x*l=
r(p,q,d)f*p,*q;{char o[81];f*n=p,i=39,*c,*u=d?q:z(p,q);o[40]='0'+(1&*p);
for(;i>=0;i--y u=d?z(p,q):q;n=p;for(i=41;i<79;i++y o[i++]='\r';o[i++]=0;
v o);(void)fflush(stdout);sleep(1);}
main(a,c)char**c;{char*u,*malloc(),*m=
"Usage: black [string]\n\0No more memory\n\0Unusable memory alignment\n\0jt,s@m@ (beleY%XX&Yz {z&z}i|R(|)*((.)i)hiniFiGJ%FG.JJgJ: ;;&;z {z&z}-RS/ROiOV OP+PsaPh+ijainnjmamfmfAlnnnnphppopv%vvgv.aABiB1/BVP11/1.%..&.OhrR-WV V1#1VP1CcC0R\
\n\n'CVP0\n!\n\n'\nEaEEnEamat!akckk'kwaww'wz,zzozEit +",
*n=m;f*q,*p=0,*g,b=3,d;
if(a>2)v m x n=a>1?c[1]:n;
/*v"\t\t\t\t\tV\n");*/
k(q)0;u=n;a=~1&'j';
while(a!='x'){
r(q,p,b);
for(;;u+=3){
u= *u?u:n;
if((~1&*u)==a&&(1&*q)<<1==(2&u[2]))break;
}
a=~1&u[1];
d=(8&u[2])>>3;
if(16&u[2])putchar(u[3]);
if(4&u[2])*q|=1;else*q&=~1;
if(b==d)g=p;else{
g=z(q,p);
if(!g){k(g)(f)q;*q^=(f)g;}
}
p=q;q=g;b=1-d;
}
r(q,p,b);v"\n");exit(0);
}
+17 -13
View File
@@ -38,7 +38,10 @@ echo -100 x 100 + 1 | ./robison
echo 100 / 100 | ./robison # <-- what happens here ?
```
NOTE: this entry will crash with numbers with non binary digits.
### INABIAF - it's not a bug it's a feature! :-)
This program will very likely crash or break into tiny bits :-) if you feed it
numbers with non-binary digits.
## Judges' remarks:
@@ -48,14 +51,15 @@ the source deck can be re-collated with an ASCII sort.
Note that this program uses only a small subset of the
constructs that the C language supports.
NOTE: this entry will likely dump core with invalid input.
For an interesting document on APL, see
<https://computerhistory.org/blog/the-apl-programming-language-source-code/>.
## Author's remarks:
This program is a handy picoAPL interpreter written in C--. It
outputs the evaluation of an APL expression from standard
input. Functions are limited to dyadic +,-,x, and unary -;
This program is a handy picoAPL interpreter written in `C--`. It
outputs the evaluation of an
[APL](https://en.wikipedia.org/wiki/APL_(programming_language)) expression from standard
input. Functions are limited to dyadic `+`,`-`,`x`, and unary `-`;
numerals must be binary. Parentheses may be used for
grouping. For example:
@@ -72,17 +76,17 @@ prints:
That is `5x(7-4)` is `15`. (APL groups from right to left.)
Extending it to the full APL language should be trivial.
The C-- language improves the C language by removing superfluous
The `C--` language improves the C language by removing superfluous
and confusing features: arithmetic, logical operations, shifts,
relationals, address-of, and flow control. In fact, the only
relational operators, address-of, and flow control. In fact, the only
expressions retained are function calls, indirection, array
assignments, the ',' operator, and sizeof. Despite these
restrictions, the C-- program does arithmetic on arbitrarily
assignments, the ',' operator, and `sizeof`. Despite these
restrictions, the `C--` program does arithmetic on arbitrarily
large binary numbers.
To obtain a C-- reference, simply rip out the irrelevant pages
from your K&R C manual. To obtain a C-- compiler, simply rip
out the irrelevant bytes from your cc compiler.
To obtain a `C--` reference, simply rip out the irrelevant pages
from your K&R C manual. To obtain a `C--` compiler, simply rip
out the irrelevant bytes from your `cc` compiler.
## Copyright and CC BY-SA 4.0 License:
+8 -11
View File
@@ -1,9 +1,6 @@
# Best layout
Lievaart, Roemer B.\
VU-Informatica, Amsterdam\
Marcusstraat 29/2,\
NL 1091 TJ Amsterdam\
Netherlands
## To build:
@@ -20,18 +17,18 @@ make all
## Judges' remarks:
Do you know what this program does? If you do, look again,
there is more here than meets the PI.
Do you know what this program does? If you do, look again, there is more here
than meets the PI.
## Author's remarks:
Passes lint, but not with the strictest options, for it
contains some "null-statements", as well two identifiers
which are, if compilers only take 6 characters, the same. It
also uses write(2), so not totally system independent.
Passes lint, but not with the strictest options, for it contains some
"null-statements", as well two identifiers which are, if compilers only take 6
characters, the same. It also uses `write(2)`, so not totally system
independent.
You are very much invited to pass this program through a C-beautifier. (First
strip newlines and tabs, if your `cb` can't do that.)
You are very much invited to pass this program through a C-beautifier (first
strip newlines and tabs, if your `cb` can't do that).
## Copyright and CC BY-SA 4.0 License:
+46 -36
View File
@@ -1,9 +1,6 @@
# Best game
John Tromp\
Centre for Mathematics and Computer Science (CWI)\
Oetgensstraat 7\
1701CK Heerhugowaard\
Netherlands
## To build:
@@ -19,39 +16,44 @@ make all
```
## Try:
```sh
./tromp 5
# fast with vim keys
# h - left (left)
# k - rotate (arbitrary, in vim k = up)
# l - right (right)
# j - drop (down)
# space - pause (literal space in vim)
# q - quit (similar to :q in vim)
./tromp 10 "hklj q"
./tromp 10 "hkl jq"
```
NOTE: after this game ends a file called `HI` will be in the directory with the
The second command, `./tromp 10 "hkl jq"`, will set up the keys kind of like
vim:
- h - left (left)
- k - rotate (up)
- l - right (right)
- j - drop (down)
- space - pause (space)
- q - quit (:q)
NOTE: after the game ends a file called `HI` will be in the directory with the
high scores (up to 20 runs saved) so one can see who has the highest score. The
file might look like:
```
330 by luser
136 by loser
100 by winner
```
... or so, where in this case the luser is the winner and the loser is the loser :-)
... or so, where in this case the [luser is the winner, the loser is in second
place and the winner is the
loser](https://web.archive.org/web/20181023221954/https://www.chicagotribune.com/news/ct-xpm-2002-07-31-0207310310-story.html) :-)
### Alternate code:
The author provided an alternate version of the code with some improvements. We
were unable to see the improvements in modern systems even after fixing it to
compile (the high score file was not created at all) but if you have an old
compiler you can try compiling it in its original unmodified form by running:
The author provided an alternate version of the code with some improvements. See
the judges' additional remarks in the author's remarks, for more details.
#### To use:
```sh
make alt
@@ -59,29 +61,33 @@ make alt
Use `tromp.alt` as you would `tromp` above.
NOTE: testing more than one user updating the high score file, one of the
benefits of the alt version, has not been done.
The original unmodified alternate code is provided later.
## Judges' remarks:
This is a character terminal version of the TETRIS program.
This is a character terminal version of the `TETRIS` game.
It runs on a VT100 compatible terminal or emulator. It is
best used at 4800 baud or more.
By default, "drops_per_sec", the number of times an object
will drop in a second, is 2. The default "cmd_string" is
"jkl pq". The first 6 characters of "cmd_string" relate
By default, `drops_per_sec`, the number of times a tetrimino
will drop in a second, is 2. The default `cmd_string` is
`jkl pq`. The first 6 characters of `cmd_string` relate
to the following 6 game commands:
- j - left
- k - rotate
- l - right
- space - drop
- space - drop
- p - pause
- q - quit
Specifying "cmd_string" allows one to re-define the commands.
Specifying `cmd_string` allows one to redefine the commands.
The pause command pauses the game, clears the screen and
prints the current score. To resume, type the pause
character again, which by default is "p".
character again, which by default is `p`.
As was stated last year, we are likely to be more strict about
portability in the future. [ We mean it this time :-) ]
@@ -89,7 +95,7 @@ portability in the future. [ We mean it this time :-) ]
## Author's remarks:
This program plays the familiar game of `TETRIS' with the
This program plays the familiar game of `TETRIS` with the
following features:
* outputs vt100-like escape-sequences for cursor
@@ -98,32 +104,34 @@ following features:
* continuously increasing speed (except in pause)
* start speed selectable by giving n as first argument,
where n is the number of drops per second (default=2).
* start speed selectable by giving `n` as first argument,
where `n` is the number of drops per second (default=2).
* controls also selectable by giving as the second argument
a string of 6 characters. By default they are "jkl pq".
a string of 6 characters. By default they are `jkl pq`.
* screen is blanked during the pause and the score is shown
* maintains a high-score table
Giving a full path name for the table will result in a
system-wide hiscore allowing a competition between users.
system-wide high-score allowing a competition between users.
### Additional remarks from the judges:
The author provided us with the following notes and new version of
the program:
Here is a somewhat improved version of my tetris entry. All the
changes are in the popen() at the end. Formerly a move was done
changes are in the `popen()` at the end. Formerly a move was done
to the HI score file which is not permitted for other users. Now
other users can change the HI score file. The extra option -m is
other users can change the `HI` score file. The extra option `-m` is
passed to sort, so that it knows that its input files are already
sorted. The -o output option of sort is used instead of a
sorted. The `-o` output option of sort is used instead of a
temporary file.
You may also want to consider giving just the raw option to stty
at the start and -raw at the end. This further reduces the size of
You may also want to consider giving just the raw option to `stty`
at the start and `-raw` at the end. This further reduces the size of
the program, but has the possible disadvantage that the program
can only by stopped by 'q' or by the `kill -9' command.
@@ -149,6 +157,8 @@ can only by stopped by 'q' or by the `kill -9' command.
"%4d from level %1d by %s\n",w,l,getlogin());pclose(d);}
```
NOTE: the alternate version was fixed for modern systems in 2023.
## Copyright and CC BY-SA 4.0 License:
This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
+9 -9
View File
@@ -1,19 +1,19 @@
long h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}c,d,l,v[]={(int)t,0,2},w,s,I,K
long h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}FILE *d;long c,l,v[]={0,0,2},w,s,I,K
=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1,
12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12,
1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12,
12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i])-Q[i]
){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);printf(
){Q[i]=k;if(i-++I||i%12<1)printf("\033[%ld;%ldH",(I=i)/12,i%12*2+28);printf(
"\033[%dm "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+
n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char*
*V,*a;{h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i<
25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v,
n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V)char*
*V;{char *a;*v=(long)t;h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i<
25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo");sigaction(14,v,
0);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<0){if(G(x+
12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){
for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c
=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G
(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock(
8192);printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]=
0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}d=popen(
"stty -cbreak echo stop \023;sort -mnr -o HI - HI;cat HI","w");fprintf(d,
"%4d from level %1d by %s\n",w,l,getlogin());pclose(d);}
8192);printf("\033[H\033[J\033[0m%ld\n",w);if(c==a[5])break;for(j=264;j--;Q[j]=
0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}system(
"stty cbreak echo");d=popen("cat - HI 2>/dev/null|sort -mnr -o HI -;cat HI","w");fprintf(d,
"%4ld from level %1ld by %s\n",w,l,getlogin());pclose(d);}
+4 -4
View File
@@ -17,26 +17,26 @@ make all
## Try:
```sh
./vanb the rug gary lent\
./vanb the rug gary lent
./vanb unix is better than os/2
```
## Judges' remarks:
This program computes all proper subsets of the set of
arguments passed to it. Each subset is printed with one\
arguments passed to it. Each subset is printed with one
element on each line, followed by a line of ten dashes.
## Author's remarks:
The program has the following charming and possibly\
The program has the following charming and possibly
non-portable features:
* It has no local or global variables, only the command-line parameters.
* It calls main recursively.
* It calls `main()` recursively.
* It alters the command-line parameters.
+2 -12
View File
@@ -536,17 +536,6 @@ or any others.
# 1987
## [1987/lievaart](1987/lievaart/lievaart.c) ([README.md](1987/lievaart/README.md))
## STATUS: possible bug (possibly depending on system) - please help test and if necessary fix
Cody fixed this to not enter an infinite loop (it was documented to detect this
but it no longer worked). However this will forfeit the game for the user and
it's not clear at this time if it was supposed to just act like you input `99`
(see the README.md for details here) but that seems probable.
Another issue might be that certain input when prompted for input will just
prompt you again for input but it might be that I (Cody) do not remember how to
play the game and it's expected this way.
# 1988
@@ -570,7 +559,8 @@ number larger than 20 did this.
## [1989/robison](1989/robison/robison.c) ([README.md](1989/robison/README.md))
## STATUS: INABIAF - please **DO NOT** fix
This program will crash with numbers with non-binary digits.
This program will very likely crash or break into tiny bits :-) if you feed it
numbers with non-binary digits.
## [1989/westley](1989/westley/westley.c) ([README.md](1989/westley/README.md))
+73 -5
View File
@@ -290,8 +290,40 @@ that for System V we had to do this) Cody added to the Makefile
## [1987/lievaart](1987/lievaart/lievaart.c) ([README.md](1987/lievaart/README.md))
Cody fixed two infinite loops showing just `You:` by detecting invalid input
which the program was documented to do. But see [bugs.md](/bugs.md).
Cody added back the documented checks for invalid input which no longer worked
and instead resulted in either accepting the level, whether or not it was a
number or out of range (see below on range). For the move it entered an infinite
loop, prompting the player with `"You:"` but not letting the player input
anything so that the screen was flooded and the game could not play.
For both the level and move it did a `scanf()` with a `%d` specifier but this
resulted in, if invalid input, either proceeding (for the level), presumably
incorrectly done as it might not even be a number (see below) or printing
`"You:"` in an infinite loop, expecting input again but not letting the player
input anything, both as noted above.
The fix is that now the specifier is a `%2s` for a `char A[100]`. For the level
if `atoi(A)>10||<0` (see next part) or `!isdigit(*A)` it goes back and prompts
again. The level is checked for >=0||<=10, perhaps incorrectly or perhaps not, because
in the code that variable is checked for `<10` and if that is the case it is
incremented by 2. I do not know the rules of the game and neither do I know what
the author had in mind so I chosen 10 as the maximum.
As for the move the `do..while` loop works properly now that it does it in two
steps (`scanf("%2s", A); m=atoi(A);`) so there's no need to check the value
explicitly, again. Thus it will prompt until valid input is entered, but only
showing `"You:"` once per prompting.
In the case of the level prior to prompting for the level it does a `*A='\0';`
and in the case of the move it does it after the `m=atoi(A);`. This is done this
way because the check for the value of the level (`atoi(A)`) is done in the
`if()` that also checks for a digit (though it does `(u=atoi(A))>10||u<0` first,
thus checking the level, and `|| !isdigit(*A)`). Of course since `-` is not a
digit the `<0` is superfluous but it's done anyway. If that `if` is 1 then it
immediately goes back to the prompting of the level.
But for the move it can happen after due to the fact the condition of the
`do..while` loop will take care of things.
Cody also made this ever so slightly like the original code by adding back the
`#define D define` even though it's unused. This was done for both versions as
@@ -470,11 +502,26 @@ entry as seeing the code with the result at once is far more beautiful.
## [1989/fubar](1989/fubar/fubar.c) ([README.md](1989/fubar/README.md]))
Cody got this to work with modern systems. The `main()` issues were an
Cody got this to work with modern systems. The main issues were that an
`#include` had to be added along with fixing the path (due to `.` not being in
`$PATH`) to files referred to in the code.
## [1989/jar.1](1989/jar.1/jar.1.c) ([README.md](1989/jar.1/README.md]))
To prevent annoying output to `/dev/tty` we changed the code to simulate the
output via `strings(1)` but Cody removed the ill-famed `useless use of cat` to
shut ShellCheck up. Why is it ill-famed? Because there is no such thing as a
useless cat, that's why! For instance, the fact they even exist is proof that
the Earth is **NOT** flat: because if it was they would have pushed everything
off it by now! :-) They're also a great joy to all ailurophiles and yes they
most certainly do have a personality and they can be very sociable.
Whilst he was at it, Cody made it so that one need not run the alt script or alt
code directly, to match that of the main entry. As we simulate the functionality
anyway, and since one may still run the code or the script (for the original
entry and the alt code) anyway, it works out well.
## [1989/jar.2](1989/jar.2/jar.2.c) ([README.md](1989/jar.2/README.md]))
Cody fixed this to work with modern compilers. Modern compilers do not allow
@@ -491,6 +538,14 @@ code like:
He notes that there _is_ a way to get it (or something close to it) to work. Do
you know how?
Cody also provided the [try.me.sh](1989/jar.2/try.me.sh) script and the
supplementary files [try.me.txt](1989/jar.2/try.me.txt),
[fib.lisp](1989/jar.2/fib.lisp) and
[chocolate_cake.lisp](1989/jar.2/chocolate_cake.lisp). The `try.me.txt` comes
from the author and the `fib.lisp` comes from Yusuke. Cody wrote the script and
offered us some chocolate cake :-) See README.md for details on how to use the
script.
## [1989/ovdluhe](1989/ovdluhe/ovdluhe.c) ([README.md](1989/ovdluhe/README.md]))
@@ -510,9 +565,12 @@ Cody fixed a segfault under macOS that prevented it from working. The problem
was that the int (from `#define f`) should be a long. This became apparent when
he was using lldb and saw that the type of a pointer was too `long` :-)
Cody also provided the [alternate version](1989/paul/paul.alt.c)
which has the trace function that the author included but commented out. See the
README.md for details.
## [1989/robison](1989/robison/robison.c) ([README.md](1989/robison/README.md]))
cd 1989/robison ; make orig_prog_diff
Yusuke Endoh fixed this to compile under modern systems. To see the changes
made, try:
@@ -534,11 +592,21 @@ To get it to work with clang the variable `a` had to not be the third argument
to `main()` but instead be a variable in `main()`.
Cody also fixed a segfault and made it so the that the high score file would
work (it was not even being created but it was supposed to be).
work (it was not even being created but it was supposed to be). This was
happening due to a file pointer being declared as a `long` and more
significantly is the command in `popen(3)` was not correct.
Another problem Cody fixed was that the terminal was left in an insane state where you
could not type '`u`' and echo was completely disabled.
Cody later on fixed the alt version, provided by the author, so that it would
compile with clang, not abort (with an alarm), would have the tetriminos fall,
it would write to the high score file (the command to `popen(3)` was incorrect
here too but as can be seen it differs from the submitted version), could use
`stty` properly (and thus turn on echo again - it did not work because it was in
the `popen(3)` call rather than using `system(3)`), a couple compiler errors and
various other things, so that now the alt version, which is better, can be used.
Although we appreciate the help here, he cynically noted that he had to have an
IOCCC [Tetris](https://en.wikipedia.org/wiki/Tetris) working (this of course was
not his only reason :-) )
+1 -1
View File
@@ -1,5 +1,5 @@
# A todo list of known things to check and/or do
*Last updated: Mon 16 Oct 11:22:52 UTC 2023*
*Last updated: Fri 20 Oct 11:59:47 UTC 2023*
This document is primarily for [Cody Boone
Ferguson](/winners.html#Cody_Boone_Ferguson) as he (that is I :-) ) wanted a way