diff --git a/1987/lievaart/Makefile b/1987/lievaart/Makefile index 0712ac348..605531004 100644 --- a/1987/lievaart/Makefile +++ b/1987/lievaart/Makefile @@ -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 # diff --git a/1987/lievaart/lievaart.c b/1987/lievaart/lievaart.c index 70e9cdfc1..79d8b8356 100644 --- a/1987/lievaart/lievaart.c +++ b/1987/lievaart/lievaart.c @@ -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;au){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;} diff --git a/1987/lievaart/lievaart2.c b/1987/lievaart/lievaart2.c index dd9d785dc..25e15cc56 100644 --- a/1987/lievaart/lievaart2.c +++ b/1987/lievaart/lievaart2.c @@ -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;aj){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 diff --git a/1989/jar.1/Makefile b/1989/jar.1/Makefile index a553faf19..fc13b9f65 100644 --- a/1989/jar.1/Makefile +++ b/1989/jar.1/Makefile @@ -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 # diff --git a/1989/jar.1/README.md b/1989/jar.1/README.md index 1bd4c1cb3..4b25cb6ac 100644 --- a/1989/jar.1/README.md +++ b/1989/jar.1/README.md @@ -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 diff --git a/1989/jar.1/jar.1.alt.sh b/1989/jar.1/jar.1.alt.sh index b9d053b54..f123c5d70 100755 --- a/1989/jar.1/jar.1.alt.sh +++ b/1989/jar.1/jar.1.alt.sh @@ -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 diff --git a/1989/jar.1/jar.1.sh b/1989/jar.1/jar.1.sh index fecb4cc0b..9c1582c6b 100755 --- a/1989/jar.1/jar.1.sh +++ b/1989/jar.1/jar.1.sh @@ -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 diff --git a/1989/jar.2/Makefile b/1989/jar.2/Makefile index 7616924c6..97904685f 100644 --- a/1989/jar.2/Makefile +++ b/1989/jar.2/Makefile @@ -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 # diff --git a/1989/jar.2/README.md b/1989/jar.2/README.md index ce4d8a1ed..d12bb3830 100644 --- a/1989/jar.2/README.md +++ b/1989/jar.2/README.md @@ -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)))) ``` diff --git a/1989/jar.2/chocolate_cake.lisp b/1989/jar.2/chocolate_cake.lisp new file mode 100644 index 000000000..9cf38cbf4 --- /dev/null +++ b/1989/jar.2/chocolate_cake.lisp @@ -0,0 +1,8 @@ +(quote ......................) +(quote ||||||||||||||||||||||) +(quote [[[--hexa-layered--]]]) +(quote [[[----layered-----]]]) +(quote [[[---chocolate----]]]) +(quote [[[-----fudge------]]]) +(quote [[[-----cake-------]]]) +(quote [[[[[[[[[[]]]]]]]]]]]]) diff --git a/1989/jar.2/fib.lisp b/1989/jar.2/fib.lisp new file mode 100644 index 000000000..8c806114b --- /dev/null +++ b/1989/jar.2/fib.lisp @@ -0,0 +1,5 @@ +(defun fib (n) + (if (< n 2) + 1 + (+ (fib (- n 2)) (fib (- n 1))))) +(fib 10) diff --git a/1989/jar.2/jar.2.c b/1989/jar.2/jar.2.c index c53aa121e..88afe74db 100644 --- a/1989/jar.2/jar.2.c +++ b/1989/jar.2/jar.2.c @@ -1,4 +1,6 @@ #include +#define d define +#define a include #include #include #define p char* diff --git a/1989/jar.2/try.me.sh b/1989/jar.2/try.me.sh new file mode 100755 index 000000000..200dbac37 --- /dev/null +++ b/1989/jar.2/try.me.sh @@ -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 diff --git a/1989/jar.2/try.me.txt b/1989/jar.2/try.me.txt new file mode 100644 index 000000000..842935b6d --- /dev/null +++ b/1989/jar.2/try.me.txt @@ -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)))) diff --git a/1989/paul/.gitignore b/1989/paul/.gitignore index d4c8f86ea..b824b34c9 100644 --- a/1989/paul/.gitignore +++ b/1989/paul/.gitignore @@ -1,3 +1,4 @@ paul +paul.alt paul.orig prog.orig diff --git a/1989/paul/Makefile b/1989/paul/Makefile index f65be869b..eb578920b 100644 --- a/1989/paul/Makefile +++ b/1989/paul/Makefile @@ -114,8 +114,8 @@ OBJ= ${PROG}.o DATA= TARGET= ${PROG} # -ALT_OBJ= -ALT_TARGET= +ALT_OBJ= ${PROG}.alt.o +ALT_TARGET= ${PROG}.alt ################# diff --git a/1989/paul/README.md b/1989/paul/README.md index 9928bc682..5596cf923 100644 --- a/1989/paul/README.md +++ b/1989/paul/README.md @@ -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. diff --git a/1989/paul/paul.alt.c b/1989/paul/paul.alt.c new file mode 100644 index 000000000..d4551a6fb --- /dev/null +++ b/1989/paul/paul.alt.c @@ -0,0 +1,35 @@ +#include +#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); +} diff --git a/1989/robison/README.md b/1989/robison/README.md index f67620e14..5f528b5e1 100644 --- a/1989/robison/README.md +++ b/1989/robison/README.md @@ -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 +. ## 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: diff --git a/1989/roemer/README.md b/1989/roemer/README.md index 5b3dd20ef..dd7ce0e51 100644 --- a/1989/roemer/README.md +++ b/1989/roemer/README.md @@ -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: diff --git a/1989/tromp/README.md b/1989/tromp/README.md index 89a5b0518..c2757a5b4 100644 --- a/1989/tromp/README.md +++ b/1989/tromp/README.md @@ -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. diff --git a/1989/tromp/tromp.alt.c b/1989/tromp/tromp.alt.c index 199789a34..cc397cd79 100644 --- a/1989/tromp/tromp.alt.c +++ b/1989/tromp/tromp.alt.c @@ -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);} diff --git a/1989/vanb/README.md b/1989/vanb/README.md index b71067432..84643c984 100644 --- a/1989/vanb/README.md +++ b/1989/vanb/README.md @@ -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. diff --git a/bugs.md b/bugs.md index 1914cdd65..87e28b8dd 100644 --- a/bugs.md +++ b/bugs.md @@ -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)) diff --git a/thanks-for-fixes.md b/thanks-for-fixes.md index 7b5de90f1..1ee144d44 100644 --- a/thanks-for-fixes.md +++ b/thanks-for-fixes.md @@ -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 :-) ) diff --git a/todo.md b/todo.md index 277d54cf4..76c8aa28e 100644 --- a/todo.md +++ b/todo.md @@ -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