Merge pull request #1491 from xexyl/gavin2004alt
Add alt code to 2004/gavin for QEMU
This commit is contained in:
13 files changed
+568
-79
No files matched your search
@@ -1,6 +1,8 @@
|
||||
fs/
|
||||
fs.tar
|
||||
gavin
|
||||
gavin.alt.o
|
||||
gavin.alt
|
||||
gavin.o
|
||||
img/gavin.c
|
||||
img/prim
|
||||
|
||||
+23
-2
@@ -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}
|
||||
|
||||
+32
-6
@@ -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 <http://bellard.org> 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
|
||||
<http://bellard.org> 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?
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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}
|
||||
|
||||
+65
-29
@@ -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:
|
||||
|
||||
Executable
+47
@@ -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
|
||||
Executable
+54
@@ -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
|
||||
@@ -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'; \
|
||||
|
||||
+18
-24
@@ -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 ...
|
||||
|
||||
Executable
+34
@@ -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"
|
||||
|
||||
Executable
+34
@@ -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
|
||||
+57
-10
@@ -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))
|
||||
|
||||
Reference in new issue
Block a user