diff --git a/2004/gavin/.gitignore b/2004/gavin/.gitignore index cf34cb6c0..fa82baa66 100644 --- a/2004/gavin/.gitignore +++ b/2004/gavin/.gitignore @@ -1,6 +1,8 @@ fs/ fs.tar gavin +gavin.alt.o +gavin.alt gavin.o img/gavin.c img/prim diff --git a/2004/gavin/Makefile b/2004/gavin/Makefile index a4a7e8a15..a1e2abb5c 100644 --- a/2004/gavin/Makefile +++ b/2004/gavin/Makefile @@ -122,8 +122,8 @@ OBJ= ${PROG}.o DATA= boot.b lilo.conf prim gavin.md TARGET= ${PROG} kernel sh vi fs.tar # -ALT_OBJ= -ALT_TARGET= +ALT_OBJ= ${PROG}.alt.o +ALT_TARGET= ${PROG}.alt kernel.alt sh.alt vi.alt fs.alt.tar ################# @@ -165,6 +165,27 @@ fs.tar: sh vi gavin.c README.md prim alt: data ${ALT_TARGET} @${TRUE} +${PROG}.alt: ${PROG}.alt.c + ${CC} ${CFLAGS} -UK -DK=1 $< -o $@ ${LDFLAGS} + +kernel.alt: ${PROG}.alt + ${RM} -f kernel + ./${PROG}.alt > kernel + +sh.alt: ${PROG}.alt.c + ${RM} -f ${PROG}.alt.o + ${CC} ${CFLAGS} -DB=_start '-Dputchar(a)=' $< -c + @echo "NOTE: this entry will not work with any platform other than x86/linux." + ${LD} -static -o sh ${PROG}.alt.o + +vi.alt: sh.alt + ${RM} -f vi + ${CP} $< vi + +fs.alt.tar: sh.alt vi.alt gavin.alt.c README.md prim + ${RM} -f $@ + ${TAR} -cvf fs.tar sh vi gavin.alt.c README.md prim + # data files # data: ${DATA} diff --git a/2004/gavin/README.md b/2004/gavin/README.md index 9b6fc16b7..8e4e99f89 100644 --- a/2004/gavin/README.md +++ b/2004/gavin/README.md @@ -5,6 +5,11 @@ make ``` +There is an alternate version for those who wish to use QEMU rather than having +to reboot and rely on having a floppy drive (if you even remember what those are +:-) ) etc. See [alternate code](#alternate-code) below. + + ### Bugs and (Mis)features: The current status of this entry is: @@ -73,6 +78,26 @@ vi README.md Press and hold any key. +## Alternate code: + +This version's main difference is that the macro `K` is redefined to `1` so that +you can use it with `QEMU`. + + +### Alternate build: + +```sh +make alt +``` + +### Alternate use: + +The use is mostly the same as `gavin` except that one initially executes `gavin.alt` +(which `make alt` will do) and one will have to use `QEMU` instead. The files +generated are the same names. See [to use](#to-use) and [try](#try) above as +well as the judges' remarks below plus [gavin.md](gavin.md). + + ## Judges' remarks: Over the years, we've seen a program that immediately dumps core if executed on @@ -86,12 +111,13 @@ future contests. If you do not want to mess with a floppy and you use GRUB, see [gavin.md](gavin.md). -You can put additional text files in `fs.tar` for browsing with vi. If you do -not want to bother rebooting your computer at all, see for -QEMU ([Fabrice Bellard](/winners.html#Fabrice_Bellard) is an IOCCC 2001 winner), -but your experience will be limited; replace `-DK=0` with `-DK=1` in the -[Makefile](Makefile), and you will have to move the mouse to trigger the initial -screen update. +You can put additional text files in `fs.tar` for browsing with vi. + +If you do not want to bother rebooting your computer at all, see + for QEMU ([Fabrice Bellard](/winners.html#Fabrice_Bellard) +is an IOCCC 2001 winner), but your experience will be limited; use the +[alternate code](#alternate-code) instead. You'll have to move the mouse to +trigger the initial screen update. The judges were able to write a few more programs to run in this OS. What are the limitations for such programs? diff --git a/2004/gavin/gavin.alt.c b/2004/gavin/gavin.alt.c new file mode 100644 index 000000000..46310f01f --- /dev/null +++ b/2004/gavin/gavin.alt.c @@ -0,0 +1,190 @@ +#undef K +#define K 1 +#ifndef Y +#define Y(m) *((int*)(m)) +#endif +#ifndef E +#define E(f,a,b,c) ((G((*)))(f))(a,b,c) +#endif +#ifndef M +#define M for(D=0;D<786432;D++) +#endif +#ifndef Z +#define Z int i=0,j=0,h,n,p=393728,s=26739,C,D +#endif +#ifndef V +#define VV 0x90200 +#endif +#ifndef R +#define R while((C=E(V-8,100,0,0))&3&&(D=E(V-8,96,0,0))|3){ +#endif +#ifndef L +#define L(c,d) E(V+8,100,c,0);R}E(V+8,96,d,0);R} +#endif + +int main(int t, char **q, char **d) { return cain(t, (int)q, (int)d); } +#define G(n) int n(int t, int q, int d) +#define X(p,t,s) (p>=t&&p<(t+s)&&(p-(t)&1023)<(s&1023)) +#define U(m) *((signed char *)(m)) +#define F if(!--q){ +#define I(s) (int)cain-(int)s +#define P(s,c,k) for(h=0; h>>14==0; h+=129)Y(16*c+h/1024+Y(V+36))&128>>(h&7)?U(s+(h&15367))=k:k + +G (B) +{ + Z; + F D = E (Y (V), C = E (Y (V), Y (t + 4) + 3, 4, 0), 2, 0); + Y (t + 12) = Y (t + 20) = i; + Y (t + 24) = 1; + Y (t + 28) = t; + Y (t + 16) = 442890; + Y (t + 28) = d = E (Y (V), s = D * 8 + 1664, 1, 0); + for (p = 0; j < s; j++, p++) + U (d + j) = i == D | j < p ? p--, 0 : (n = U (C + 512 + i++)) < ' ' ? p |= + n * 56 - 497, 0 : n; +} + +n = Y (Y (t + 4)) & 1; +F +U (Y (t + 28) + 1536) |= +62 & -n; +M +U (d + D) = +X (D, Y (t + 12) + 26628, 412162) ? X (D, Y (t + 12) + 27653, + 410112) ? 31 : 0 : U (d + D); +for (; j < 12800; j += 8) + P (d + 27653 + Y (t + 12) + ' ' * (j & ~511) + j % 512, + U (Y (t + 28) + j / 8 + 64 * Y (t + 20)), 0); +} + +F if (n) + { + D = Y (t + 28); + if (d - 10) + U (++Y (t + 24) + D + 1535) = d; + else + { + for (i = D; i < D + 1600; i++) + U (i) = U (i + 64); + Y (t + 24) = 1; + E (Y (V), i - 127, 3, 0); + } + } +else + Y (t + 20) += ((d >> 4) ^ (d >> 5)) - 3; +} +} + +G (_); +G (o); +G (cain) +{ + Z, k = K; + if (!t) + { + Y (V) = V + 208 - (I (_)); + L (209, 223) L (168, 0) L (212, 244) _((int) &s, 3, 0); + for (; 1;) + R n = Y (V - 12); + if (C & ' ') + { + k++; + k %= 3; + if (k < 2) + { + Y (j) -= p; + Y (j) += p += U (&D) * (1 - k * 1025); + if (k) + goto y; + } + else + { + for (C = V - 20; + !i && D & 1 && n + && (X (p, Y (n + 12), Y (n + 16)) ? j = n + 12, Y (C + 8) = + Y (n + 8), Y (n + 8) = Y (V - 12), Y (V - 12) = + n, 0 : n); C = n, n = Y (n + 8)); + i = D & 1; + j &= -i; + } + } + else if (128 & ~D) + { + E (Y (n), n, 3, U (V + D % 64 + 131) ^ 32); + n = Y (V - 12); + y:C = 1 << 24; + M U (C + D) = 125; + o (n, 0, C); + P (C + p - 8196, 88, 0); + M U (Y (0x11028) + D) = U (C + D); + } + } +} + +for (D = 720; D > -3888; D--) + putchar (D > + 0 ? + " )!\320\234\360\256\370\256 0\230F .,mnbvcxz ;lkjhgfdsa \n][poiuytrewq =-0987654321 \357\262 \337\337 \357\272 \337\337 ( )\"\343\312F\320!/ !\230 26!/\16 K>!/\16\332 \4\16\251\0160\355&\2271\20\2300\355`x{0\355\347\2560 \237qpa%\231o!\230 \337\337\337 , )\"K\240 \343\316qrpxzy\0 sRDh\16\313\212u\343\314qrzy !0( " + [D] ^ 32 : Y (I (D))); +return 0; +} + +G (o) +{ + Z; + if (t) + { + C = Y (t + 12); + j = Y (t + 16); + o (Y (t + 8), 0, d); + M U (d + D) = + X (D, C, j) ? X (D, C + 1025, j - 2050) ? X (D, C + 2050, + j - 3075) ? X (D, + C + 2050, + j - + 4100) ? + X (D, C + 4100, + ((j & 1023) + 18424)) ? 176 : 24 : 20 : 28 : 0 : U (d + D); + for (n = Y (t + 4); U (i + n); i++) + P (d + Y (t + 12) + 5126 + i * 8, U (n + i), 31); + E (Y (t), t, 2, d); + } +} + +G (_) +{ + Z = Y (V + 24); + F Y (V - 16) += t; + D = Y (V - 16) - t; +} + +F for (i = 124; i < 135; i++) + D = D << 3 | Y (t + i) & 7; +} + +if (q > 0) + { + for (; n = U (D + i); i++) + if (n - U (t + i)) + { + D += _(D, 2, 0) + 1023 & ~511; + i = ~0; + } + F if (Y (D)) + { + n = _(164, 1, 0); + Y (n + 8) = Y (V - 12); + Y (V - 12) = n; + Y (n + 4) = i = n + 64; + for (; j < 96; j++) + Y (i + j) = Y (t + j); + i = D + 512; + j = i + Y (i + 32); + for (; Y (j + 12) != Y (i + 24); j += 40); + E (Y (n) = Y (j + 16) + i, n, 1, 0); + } + } +} + +return D; +} diff --git a/2005/aidan/Makefile b/2005/aidan/Makefile index 208a5b4d4..9879a1279 100644 --- a/2005/aidan/Makefile +++ b/2005/aidan/Makefile @@ -132,6 +132,12 @@ all: data ${TARGET} ${PROG}: ${PROG}.c ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} +test: test-su.perl + ${PERL} $< + +test-n0: test-su.perl + ${PERL} $< -n 0 + # alternative executable # alt: data ${ALT_TARGET} diff --git a/2005/aidan/README.md b/2005/aidan/README.md index a6b99b17a..22889db54 100644 --- a/2005/aidan/README.md +++ b/2005/aidan/README.md @@ -4,6 +4,9 @@ make ``` +There is an alternate version based on the author's remarks. See [alternate +code](#alternate-code). + ## To use: @@ -11,6 +14,7 @@ make ./aidan < puzzle ./aidan seed + ``` where `seed` is a number. @@ -19,9 +23,32 @@ where `seed` is a number. ### Try: ```sh -./aidan < insane1.sudoku +./try.sh +``` -./aidan 42 + +## Alternate code: + +This code is formatted differently and is not the approach used by the author +which is slower, inelegant and not as obscure, as the author put it. + + +### Alternate build: + +```sh +make alt +``` + + +### Alternate use: + +Use `aidan.alt` as you would `aidan` above. + + +### Alternate try: + +```sh +./try.alt.sh ``` @@ -30,15 +57,12 @@ where `seed` is a number. Are you puzzled about puzzles? This entry might puzzle you more while it puzzles out some puzzles: all in a puzzling way! -`Goto` the source and notice the lack of functions. Jump +`goto` the source and notice the lack of functions. Jump to the `switch` statement. And if you think you can puzzle it out better, try solving [insane1.sudoku](insane1.sudoku) all by yourself! -NOTE: some of the files listed below by the author were either removed or -renamed. The removed file in question was a tarball but the files were extracted -into the directory instead. These files were added to the list. We also removed -the README.md which was at one point named `sudoku-sf.txt`. The author submitted -the program as `sudoku-sf.c` which was renamed and changed in their comments. +NOTE: the tarball named by the author was removed after the files were extracted +into the directory instead. These files were added to the list. ## Author's remarks: @@ -47,9 +71,9 @@ This program can solve a type of logic puzzle known as a [Sudoku](https://en.wikipedia.org/wiki/Sudoku), and also generate new ones. + ### Contents -* build file: build.txt - you don't need this * program file: [aidan.c](aidan.c) - sudoku solver and generator * test suite: [test-su.perl](test-su.perl) - optional test script (written for Perl5) * sudoku file: [blank.sudoku](blank.sudoku) @@ -65,6 +89,7 @@ generate new ones. Yes, the test suite really is 5 times larger than the actual program. You **did** say this was a parody of the software development process... + ### IMPORTANT [test.perl](test-su.perl) expects the `sudoku-sf` executable to be @@ -73,6 +98,7 @@ new name. > Judges' note: this was done. + ### Legal blurb This program comes with NO WARRANTY, not even that it'll do what I say it @@ -82,13 +108,14 @@ Go find some unpopular multinational to sue instead. This program is not copyrighted and is entirely my work. Distribute or modify it as you wish, though please give me credit. + ### What is a sudoku? (If you know, feel free to skip this section. Get more details from [the wikipedia entry](http://en.wikipedia.org/wiki/Sudoku)) A sudoku is a type of logic puzzle. You are given a grid of 9x9 boxes, some -of which contain digits. This is divided into nine 3x3 boxes, e.g. (from the +of which contain digits. This is divided into a 3x3 set up, e.g. (from the Wikipedia article - fairly easy): ``` @@ -136,18 +163,18 @@ Oh, and if you think that example sudoku is too easy, try this one (which my program generated): ``` - --- insane1.sudoku -- - . . 4 | . . . | . 5 6 - 5 . . | . 7 2 | . . . - . . 1 | . . . | 8 . . - ------+-------+------ - . . . | . . . | . . . - . . . | 6 9 3 | . . 5 - . . . | . . . | 7 3 4 - ------+-------+------ - . 5 . | 2 . 1 | 4 . 8 - 3 . . | . . . | . . . - . . . | . . . | . 6 1 +--- insane1.sudoku -- +. . 4 | . . . | . 5 6 +5 . . | . 7 2 | . . . +. . 1 | . . . | 8 . . +------+-------+------ +. . . | . . . | . . . +. . . | 6 9 3 | . . 5 +. . . | . . . | 7 3 4 +------+-------+------ +. 5 . | 2 . 1 | 4 . 8 +3 . . | . . . | . . . +. . . | . . . | . 6 1 ``` Be warned - it's evil! (I certainly haven't been able to solve it by hand. The @@ -155,6 +182,7 @@ brute-force program given above, `sudoku-bfi.c` ([aidan.alt.c](aidan.alt.c)), also has trouble - it took 66 seconds to solve it - but probably for different reasons. That's the worst performance I've had from brute-force so far!) + ### Usage #### Building @@ -181,6 +209,7 @@ somewhat slow (should take under a minute on a fairly modern PC - try appending `-n 0` if you're in a hurry). I wrote it mostly for my own benefit, really. + #### Solving ```sh @@ -188,19 +217,20 @@ really. ``` Input should be the numbers of each row in turn. Empty spaces can be -represented as a full stop (.) or zero (0). Other characters are ignored, so you -can cut-and-paste either example sudoku from above into a file and feed that +represented as a full stop (`.`) or zero (`0`). Other characters are ignored, so you +can cut-and-paste either example sudoku puzzle from above into a file and feed that in. The program has coped with every input I've thrown at it so far, including an [empty grid](blank.sudoku). Output consists of the problem, then the solution, then a message of success/failure. -`./aidan` (capital `U`), may also be useful, or perhaps not. It only took +`./aidan U` may also be useful, or perhaps not. It only took an extra 15 bytes of (very simple) code to add, so it doesn't really matter to me. (It's the same as the normal mode for most input you're likely to feed it, though slightly slower. See if you can figure out what it does.) + #### Generating ```sh @@ -211,6 +241,7 @@ Output is a blank grid, then the solution, then the problem. There's no control over the difficulty. Sorry. However, all generated sudokus should have exactly one solution - if one doesn't, that's a bug. + ### Speed Fast enough. Solving and generating are practically instant on my 1Ghz Duron. @@ -221,6 +252,7 @@ in tests on my PC (1Ghz Duron, gcc 3.4.1, `-O2` optimisation - takes about 60 seconds with no optimisation). If that isn't fast enough, what on Earth are you doing with it? + ### Bugs None known - hopefully I've worked out all the major ones. Nothing has come up @@ -237,6 +269,7 @@ generate a sudoku as a bug - just a minor quirk. The fix is slightly awkward and would make the program slightly longer, so I haven't bothered - it's not important. + ### Missing Features * No control over the difficulty of generated sudokus - they vary from easy to @@ -249,15 +282,16 @@ hurry. but I don't feel like learning curses just for this. Besides, I spent enough of the time swearing as it is. -* If you mistype a sudoku (e.g. from a paper/magazine) - and you will - it\ +* If you mistype a sudoku (e.g. from a paper/magazine) - and you will - it can't help you figure out where the mistake is, sadly. + ### Portability -Dependant on ASCII, requires that an int is at least 15 bits and a long at +Dependant on ASCII, requires that an `int` is at least 15 bits and a `long` at least 32. (No, that isn't a typo - I did say 15, not 16). -Also requires that cpp can properly handle something like: +Also requires that `cpp` can properly handle something like: ```c #define foo(x,y) x y @@ -269,17 +303,19 @@ though it usually does). Unfortunately, I didn't discover this issue until too late. (It was mentioned in the notes for people modifying GCC in the "beware of obscure compiler limitations" section, so I'm figuring it's quite unusual.) + ### Compiler warnings Some when compiled with `gcc -Wall -Wextra -ansi -pedantic`: -* The left-hand operand of a comma has no effect in two places +* The left-hand operand of a comma has no effect in two places. * Parentheses are suggested around a `+` in an operand of `&` in the `i` macro definition. Borland C also spots some code in expressions which has no effect, and some uses of `=` where you'd expect a comparison operator. + ### Obfuscation Let's see now: diff --git a/2005/aidan/try.alt.sh b/2005/aidan/try.alt.sh new file mode 100755 index 000000000..2fd1e79d0 --- /dev/null +++ b/2005/aidan/try.alt.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# +# try.sh - demonstrate IOCCC winner 2005/aidan alt code +# + +# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it +# this way allows us to have the user specify a different compiler in an easy +# way. +if [[ -z "$CC" ]]; then + CC="cc" +fi + +make CC="$CC" everything >/dev/null || exit 1 + +# clear screen after compilation so that only the entry is shown +clear + +AIDAN="aidan.alt" + +echo "When looking at the output, notice how some of the output is different" 1>&2 +echo "from the aidan.c." 1>&2 +echo 1>&2 + +read -r -n 1 -p "Press any key to continue: " +echo "$ ./$AIDAN < blank.sudoku" 1>&2 +./"$AIDAN" < blank.sudoku +echo 1>&2 + +read -r -n 1 -p "Press any key to continue: " + + +echo "$ echo IOCCC | ./$AIDAN" 1>&2 +echo IOCCC | ./"$AIDAN" +echo "What just happened?" 1>&2 +echo 1>&2 + +echo "$ echo IOCCC | ./$AIDAN 42" 1>&2 +read -r -n 1 -p "Press any key to continue (q = exit pager space = go down a page): " +echo IOCCC | ./"$AIDAN" 42 1>&2 +echo "Seeing that, was the 'echo IOCCC' relevant?" 1>&2 +echo 1>&2 + +echo "$ ./$AIDAN < insane1.sudoku" 1>&2 +read -r -n 1 -p "Press any key to continue: " +./"$AIDAN" < insane1.sudoku +echo "Did you notice how much slower this is than aidan? If not try try.sh!" 1>&2 +echo 1>&2 diff --git a/2005/aidan/try.sh b/2005/aidan/try.sh new file mode 100755 index 000000000..6c930e728 --- /dev/null +++ b/2005/aidan/try.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# +# try.sh - demonstrate IOCCC winner 2005/aidan +# + +# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it +# this way allows us to have the user specify a different compiler in an easy +# way. +if [[ -z "$CC" ]]; then + CC="cc" +fi + +make CC="$CC" all >/dev/null || exit 1 + +# clear screen after compilation so that only the entry is shown +clear + +AIDAN="aidan" + +echo "$ ./$AIDAN < blank.sudoku" 1>&2 +./"$AIDAN" < blank.sudoku +echo 1>&2 + +echo "$ ./$AIDAN U < blank.sudoku" 1>&2 +read -r -n 1 -p "Press any key to continue: " +./"$AIDAN" U < blank.sudoku +echo "What was the difference between the previous command?" 1>&2 +echo "More specifically, what did it do?" 1>&2 +echo 1>&2 + +read -r -n 1 -p "Press any key to continue: " +echo "$ echo IOCCC | ./$AIDAN" 1>&2 +echo IOCCC | ./"$AIDAN" +echo "What just happened?" 1>&2 +echo 1>&2 + +echo 1>&2 +echo "$ echo IOCCC | ./$AIDAN 42 | less -r" 1>&2 +read -r -n 1 -p "Press any key to continue (q = exit pager space = go down a page): " +echo IOCCC | ./"$AIDAN" 42 | less -r +echo "Seeing that, was the 'echo IOCCC' relevant?" 1>&2 +echo 1>&2 + +echo "$ ./$AIDAN < insane1.sudoku" 1>&2 +read -r -n 1 -p "Press any key to continue: " +./"$AIDAN" < insane1.sudoku + +read -r -n 1 -p "Do you with to run the test suite (y/n)? " +if [[ "$REPLY" = "y" ]]; then + echo 1>&2 + echo "$ make test" 1>&2 + read -r -n 1 -p "Press any key to continue: " + make test +fi diff --git a/2005/giljade/Makefile b/2005/giljade/Makefile index 55ff10e76..ae26f1df9 100644 --- a/2005/giljade/Makefile +++ b/2005/giljade/Makefile @@ -119,8 +119,8 @@ OBJ= ${PROG}.o DATA= TARGET= ${PROG} # -ALT_OBJ= ${PROG}.alt.o -ALT_TARGET= ${PROG}.alt +ALT_OBJ= +ALT_TARGET= ################# @@ -136,18 +136,16 @@ all: data ${TARGET} sandwich supernova deep_magic magic charon pluto ${PROG}: ${PROG}.c - @echo "NOTE: this version cannot successfully run the self-test. Use make alt" - @echo "for a version which will work. See README.md for why it is this way." ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} +test: ${PROG} test.sh + ./test.sh + # alternative executable # alt: data ${ALT_TARGET} @${TRUE} -${PROG}.alt: ${PROG}.alt.c - ${CC} ${CFLAGS} $< -o $@ ${LDFLAGS} - # data files # data: ${DATA} @@ -212,7 +210,7 @@ clean: fi clobber: clean - ${RM} -f ${TARGET} ${ALT_TARGET} + ${RM} -f ${TARGET} ${ALT_TARGET} out @-if [ -e sandwich ]; then \ ${RM} -f sandwich; \ echo 'ate sandwich'; \ diff --git a/2005/giljade/README.md b/2005/giljade/README.md index 72002b2fd..19a2f4fe5 100644 --- a/2005/giljade/README.md +++ b/2005/giljade/README.md @@ -4,17 +4,6 @@ make ``` -NOTE: if you do not have access to a compiler that lets you have alternative arg -types to `main()` the self-test feature will fail. If your compiler does not -have this defect you can use the Alternate code described below. The reason to -have it as the alternate version is that there is more to the entry that can -still be enjoyed with compilers with the `main()` args defect including the -primary purpose of the entry, a puzzle. - -Hopefully this will be resolved in time where there is no need for an alternate -version but it's a complicated one. See also the [bugs.md](/bugs.md) file for -more information. - ### Bugs and (Mis)features: @@ -45,7 +34,7 @@ Open an xterm with 78 lines. vi out ``` -Press ^F (control F) repeatedly. +Press `^F` (control F) repeatedly. ### Self-test feature to try: @@ -58,9 +47,10 @@ Press ^F (control F) repeatedly. ## Judges' remarks: -This entry takes editorial in how it deals with its output. After using -vi to look at the source, use vi to look at its output. We especially -recommend it on a 78 column xterm while leaning on Control-F. +This entry takes editorial in how it deals with its output. After using `vi(1)` +(or `vim(1)`) to look at the source, use `vi(1)` (or `vim(1)`) to look at its +output. We especially recommend it on a 78 column xterm while leaning on +Control-F. If you really understand expressions, then understand this: @@ -76,9 +66,10 @@ s=s^(b=s&s-1^s) ### So what do we have here ? Just run the executable with no command line args and look at the output. In -order to properly enjoy it you will need two good old programs: xterm and vi. -Do the following: open an xterm with precisely 78 lines, and use the tiny font -size for best results. Then vi (vim will also do) the output. Type `^F` +order to properly enjoy it you will need two good old programs: `xterm(1)` and +`vi(1)` (or `vim(1)`). +Do the following: open an `xterm(1)` with precisely 78 lines, and use the tiny font +size for best results. Then `vi(1)` (`vim(1)` will also do) the output. Type `^F` repeatedly or hold it down and enjoy the show ... The program solves (very very fast) a sliding block puzzle. There are many @@ -100,7 +91,7 @@ Actually, This program is smarter than merely printing ITSELF in 180 different layouts. It is self-improving, in that the programs it prints have three advantages over the original: -1. Their layout is more precise (Notice the annoying \ at the 10'th line of +1. Their layout is more precise (Notice the annoying `\` at the 10'th line of the original program which is actually a 'layout bug'). 2. Their binary output does not rely on the source file being in the same @@ -108,7 +99,7 @@ directory, and will not dump core if it doesn't (like the original does). :) 3. They have much more comments (Not very helpful ones though). -In addition as we all know bugs can creep on us in the most unexpected of +In addition as we all know bugs can creep up on us in the most unexpected of places, and checking that indeed the output is composed of 180 legal C programs by hand can be quite tedious, hence the program also include a self- test mode. Just run it with the output file as command line argument. It will @@ -124,7 +115,8 @@ but this can easily be done. Try it and diff the output of any of the 180 results with the original output. Of course all 180 programs also include the self-test mode. -### Why I think this program is obfuscated. + +### Why I think this program is obfuscated * Because it says so, and twice is better than once! * All the usual suspects i.e. `?:`, `&&`, `||`, `,` used to compress code @@ -134,7 +126,7 @@ variable names, etc... the algorithm that is used to generate possible moves is extremely efficient. In fact it can compute several moves in parallel on one processor! Moreover - Only the most efficient bitwise logical operations, shift,and subtraction by + only the most efficient bitwise logical operations, shift,and subtraction by one is used. No inefficient conditional tests and jumps are needed in that part of the program. * The single expression I'm most proud of, and would have submitted to the @@ -154,9 +146,10 @@ interesting. when returning to it now I had to sweat quite a lot to understand the f\*\*\*ing mess I've made. + ### Known Bugs/problems/warnings/portability issues -Some `CPP`s issue a warning about empty macro parameters. +Some `cpp`s issue a warning about empty macro parameters. `-pedantic` informs me that 'ISO C' does not allow extra ; outside of a function, and to this I say to ISO what ??? @@ -166,7 +159,7 @@ and remove some unnecessary expressions, and to this I say: if I listen to you where is my freedom to obfuscate in style? As mentioned earlier if you try to run the original program without its source -nearby it will dump core. +in the working directory it will dump core. The program relies heavily on the ASCII coding system (have I seen this comment before ?). It also implicitly assumes that `sizeof(int) = sizeof(FILE @@ -191,6 +184,7 @@ program. Use the program to solve for board size different than `4*5`. That's a bit more tricky. + ### Hint for the challenges Just try to change the program, and use the self test to see what happens ... diff --git a/2005/giljade/test.sh b/2005/giljade/test.sh new file mode 100755 index 000000000..7611ef025 --- /dev/null +++ b/2005/giljade/test.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# +# test.sh - demonstrate IOCCC winner 2005/giljade test suite feature +# + +# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it +# this way allows us to have the user specify a different compiler in an easy +# way. +if [[ -z "$CC" ]]; then + CC="cc" +fi + +make CC="$CC" all >/dev/null || exit 1 + +GILJADE="giljade" +EXIT_CODE=0 + +rm -f out out.count + +./"$GILJADE" > out +./"$GILJADE" out | tee out.count | grep '^Line' +COUNT="$(grep -c '^Line' out.count)" + +if [[ "$COUNT" != 180 ]]; then + echo "FAIL: expected 180 versions, got $COUNT" 1>&2 + EXIT_CODE=1 +else + echo "Found all 180 versions!" 1>&2 +fi + +rm -f out out.count + +exit "$EXIT_CODE" + diff --git a/2005/giljade/try.sh b/2005/giljade/try.sh new file mode 100755 index 000000000..233bd7535 --- /dev/null +++ b/2005/giljade/try.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# +# try.sh - demonstrate IOCCC winner 2005/giljade +# + +# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it +# this way allows us to have the user specify a different compiler in an easy +# way. +if [[ -z "$CC" ]]; then + CC="cc" +fi + +make CC="$CC" all >/dev/null || exit 1 + +# clear screen after compilation so that only the entry is shown +clear + +read -r -p "Do you wish to run the test suite (y/n) ? " +if [[ "$REPLY" == "y" ]]; then + echo "$ make test" 1>&2 + make test +fi + +echo 1>&2 +echo "$ ./giljade > out" 1>&2 +./giljade > out +echo "For this next step, make sure to keep pressing space (or hold it down) (q = quit)." 1>&2 +echo "$ less out" 1>&2 +read -r -n 1 -p "Press any key to continue: " +less out + +echo "We've left the file 'out' for you in case you wish to open it in vi(m). If" 1>&2 +echo "you do we recommend you try holding ctrl-f down in a similar way to how you held" 1>&2 +echo "down space above. Of course you can open it in another editor if you wish." 1>&2 diff --git a/thanks-for-fixes.md b/thanks-for-fixes.md index 24c9c29f7..b3346ee75 100644 --- a/thanks-for-fixes.md +++ b/thanks-for-fixes.md @@ -15,8 +15,9 @@ responsible for most of the improvements and fixes including many **EXTREMELY HARD bug fixes** like [1988/phillipps](/thanks-for-fixes.md#1988phillipps-readmemd), [1992/vern](/thanks-for-fixes.md#1992vern-readmemd), -[2001/anonymous](/thanks-for-fixes.md#2001anonymous-readmemd) and -[2004/burley](/thanks-for-fixes.md#2004burley-readmemd), making entries like +[2001/anonymous](/thanks-for-fixes.md#2001anonymous-readmemd), +[2004/burley](/thanks-for-fixes.md#2004burley-readmemd) and +[2005/giljade](/thanks-for-fixes.md#2005giljade-readmemd), making entries like [1985/sicherman](/thanks-for-fixes.md#1985sicherman-readmemd) and [1986/wall](/thanks-for-fixes.md#1986wall-readmemd) not need `-traditional-cpp` (all **EXTREMELY HARD**), fixing entries to work with clang (some being @@ -2727,6 +2728,10 @@ provided, found under the [img/](2004/gavin/img/) directory. Note that the done this way to prevent extraction from the entry directory overwriting the files and causing `make clobber` to wipe some of them out. +Cody provided the [alt code](2004/gavin/README.md#alternate-code) for those who +want to use QEMU. The most important part of this is the macro `K` has to be +defined as `1`, not `0`. + ## [2004/jdalbec](2004/jdalbec/jdalbec.c) ([README.md](2004/jdalbec/README.md)) @@ -2861,6 +2866,17 @@ Cody fixed the test script, described by the author in their remarks, to refer to the proper compiled program (it's hardcoded). This had never been done and it broke the script. +He also added the [alt code](2005/aidan/README.md#alternate-code) based on the +author's remarks which is a different approach than the one used and which 'is +slower (particularly in worst-case or nearly so scenarios), inelegant, and not a +good starting place for sudoku generation.' + +The [try.sh](2005/aidan/try.sh) and [try.alt.sh](2005/aidan/try.alt.sh) +correspond to the entry and alt code respectively. + +Cody added the `make test` and `make test-n0` rules for easier use of the test +suite. + ## [2005/anon](2005/anon/anon.c) ([README.md](2005/anon/README.md])) @@ -2894,18 +2910,49 @@ as it caused a compilation error in some of the generated code but served no purpose, didn't affect the output of the puzzle and since the 'string' is already in the code there is no problem omitting it. -`main()` was also changed to be in the old format: +The most complicated fix was for, as might be expected, `clang`: it (at least +some systems?) has `-Werror` by default so the program was changed to use `make` +and then `rm -f` on the output of the compiled binary instead. This change might +also not have been necessary if using different flags to `cc` but this is less +portable and caused other problems. This was a complicated fix as it's in the +comments but in a funny way; the final result to get the test feature to work +is: -```diff --(B[h]=N-B,N= N+6);}main(int Z,char**Y ){char*U=Z ; -+(B[h]=N-B,N= N+6);}main(Z,Y )char**Y;{char*U=Z ; +```c +;; /*echo/Line/%d;sed/-n/-e/ %d,%dp/%s/|sed*/ +/*-e/'s,intZ,int/ Z,g'>c.c;make/c;/ rm/-f/c*/ +;; ``` -Finally because clang has `-Werror` by default the program was changed to use -`make` and then `rm -f` on the output of the compiler instead. This change might -also not have been necessary if using different flags to `cc` but this felt -cleaner, somehow. +changed from: +```c +;; /*echo/Line/%d;sed/-n/-e/ %d,%dp/%s>*/ +/*c.c;cc/c.c /-c*/;; +``` + +or as a diff: + + +```diff +-(t(m),(0));; /*echo/Line/%d;sed/-n/-e/ %d,%dp/%s>*/ +-/*c.c;cc/c.c /-c*/;;char*A=0,*_,*R,*Q, D[9999],*r,l +-[9999],T=42, M,V=32;long*E,k[9999],B[1 <<+21],*N=B+ ++(t(m),(0));; /*echo/Line/%d;sed/-n/-e/ %d,%dp/%s/|sed*/ ++/*-e/'s,intZ,int/ Z,g'>c.c;make/c;/ rm/-f/c*/ ++;;char*A=0,*_,*R,*Q, D[9999],*r,l[9999],T=42, M,V=32;int *E,k[9999],B[1 <<+21],*N=B+ +``` + +Cody also added the [try.sh](2005/giljade/try.sh) script which also lets one see +the beauty of the entry without having to use vi(m), should they be afraid of +getting stuck in it (and for ease of use). :-) + +Finally, to improve upon the test-suite provided by the program, Cody added the +`make test` rule which only shows lines matching `'^Line'` but writing to a +temporary file the compilation including the 'Line' lines. After that is done it +uses `grep -c` on the file to show that there are indeed as many versions the +program generates as the author states, 180. If it does not find 180 it is an +error; otherwise it is success. It uses [test.sh](2005/giljade/test.sh). ## [2005/jetro](2005/jetro/jetro.c) ([README.md](2005/jetro/README.md))