diff --git a/2004/jdalbec/.gitignore b/2004/jdalbec/.gitignore index 9131cb521..a10a1afff 100644 --- a/2004/jdalbec/.gitignore +++ b/2004/jdalbec/.gitignore @@ -3,3 +3,6 @@ jdalbec2.c jdalbec3.c jdalbec.orig prog.orig +jdalbec3.alt.c +jdalbec2.alt.c +jdalbec.alt diff --git a/2004/jdalbec/Makefile b/2004/jdalbec/Makefile index d40cf04fd..71898ef34 100644 --- a/2004/jdalbec/Makefile +++ b/2004/jdalbec/Makefile @@ -58,7 +58,7 @@ ARCH= # Defines that are needed to compile # -CDEFINE= +CDEFINE= -DAg=11 # Include files that are needed to compile # @@ -113,8 +113,8 @@ OBJ= ${PROG}.o DATA= TARGET= ${PROG} # -ALT_OBJ= -ALT_TARGET= +ALT_OBJ= ${PROG}.alt.o +ALT_TARGET= ${PROG}.alt ################# @@ -141,6 +141,14 @@ ${PROG}: ${PROG}.c alt: data ${ALT_TARGET} @${TRUE} +${PROG}.alt: ${PROG}.alt.c + @${RM} -f ${PROG}2.alt.c $@ + -${CC} ${CSILENCE} -E ${PROG}.alt.c > ${PROG}2.alt.c + @${RM} -f ${PROG}3.alt.c + ${SED} -e 's/ (/(/g' < ${PROG}2.alt.c > ${PROG}3.alt.c + ${CC} ${CFLAGS} ${PROG}3.alt.c -o $@ ${LDFLAGS} + + # data files # data: ${DATA} diff --git a/2004/jdalbec/README.md b/2004/jdalbec/README.md index 9e5017088..041f9f023 100644 --- a/2004/jdalbec/README.md +++ b/2004/jdalbec/README.md @@ -4,6 +4,20 @@ make ``` +There is an alternate version that allows one to control the number of numbers +to print on a line. See [alternate code](#alternate-code) below. + + +### Bugs and (Mis)features: + +The current status of this entry is: + +``` +STATUS: INABIAF - please **DO NOT** fix +``` + +For more detailed information see [2004 jdalbec in bugs.md](/bugs.md#2004-jdalbec). + ## To use: @@ -15,10 +29,50 @@ make ### Try: ```sh -./jdalbec 1 -./jdalbec 11 -./jdalbec 1 1 +./try.sh +``` +## Alternate code: + +This version lets you control how many numbers to show on a line before adding a +newline as it can be harder to see when there are a lot of numbers. For lines +that don't end up having too many line breaks it also makes it easier to see +which line it is on. + + +### Alternate build: + +```sh +make alt +``` + +The macro `Ag` ([silver](https://en.wikipedia.org/wiki/Silver)) controls how +many number of lines to print on a line. Set at default to 11 protons, salt, if +you wish to make it silver, 47 (a prime) protons, do: + + +```sh +make clobber CDEFINE="-DAg=47" alt +``` + +though it might be odd to have 47 numbers on a line as it would defeat the +purpose. :-) Or if you prefer some prime, golden irony: + + +```sh +make clobber CDEFINE="-DAg=79" alt +``` + + +### Alternate use: + +Use `jdalbec.alt` as you would `jdalbec` above. + + +### Alternate try: + +```sh +./try.alt.sh ``` @@ -113,15 +167,16 @@ line 3 because the compiler doesn't recognize `??=` as a trigraph step on Mac OS X 10.1.5 generates lots of errors in "smart mode" because the "smart" preprocessor expects a valid C program as input. The preprocessor then falls back to "basic -mode" and preprocesses `jdalbec.c` successfully without warnings, +mode" and preprocesses [jdalbec.c](jdalbec.c) successfully without warnings, even when I give it the `-Wall -pedantic` options. It inserts a lot of extra spaces into the preprocessed output which is -why I had to add the `ed` step to the build file so that my +why I had to add the `ed(1)` step to the build file so that my macro `#defines` would work. The compile step gives the usual messages with `-Wall -pedantic`. The link step generates a warning about a name conflict between my `BC()` and a `BC()` from curses in the main system library. + ### BUGS FEATURES: Arguments matching `/[^2]22$/` cause the program to segfault @@ -156,6 +211,7 @@ Although there are no comments, the program still manages to be self-documenting in an obscure fashion (periodic table of the (non-primordial) elements, "OBFUSCATED C"). + ### Obfuscation The program is obfuscated: @@ -170,7 +226,7 @@ highly unstable) for `abort()`.) By overloading symbols (For example, `B` is a type, a structure, a structure member, a macro parameter, and a variable.). - By standard tricks like writing `'\0'` as `1["3"]` or `2["22"]`. - By using ternary operators to avoid `else`. -- By using the Sb function to create sub-buffers from either end. +- By using the `Sb()` function to create sub-buffers from either end. - By naming everything after chemical elements or pairs of elements. - Because it says so in the source. ;) diff --git a/2004/jdalbec/jdalbec.alt.c b/2004/jdalbec/jdalbec.alt.c new file mode 100644 index 000000000..b8ed2be8e --- /dev/null +++ b/2004/jdalbec/jdalbec.alt.c @@ -0,0 +1,214 @@ +??= define Ba BC(B, I) +??= define Be BC(Br, I) +??= define Ca(C, Ca) CB(B, In C, Ca) +??= define Cl(Cl) Cl Cl +??= define Cs const +??= define FrB N = Zr; Fr((O, B = BrB(BrF, I))) +??= define Fe(F) FO (In = Zr; F; In++) +??= define FF FB(B); FB(BF); +??= define FI Fe(IO) +??= define FO for +??= define Fr(F) FO (I = Zr; F; I++) +??= define II I I, In +??= define In(I, Ir) main(I, Ir) +??= define IO In[O[C + I]] +??= define Ir(I) if (I) +??= define Nb N > N && N > -O +??= define Rb(Rb, B) BBr(Br, Rb, B) +??= define Re return +??= define Sc struct +??= define Si(Te) sizeof (Te) +??= define Te typedef +??= define Zn N < Zr + +Te char C; +Te int I; +Te size_t Si; +Te void V; + +Cs C *Na = + + "H " "He " + "Li Be " "B C N O F Ne " + "Na Mg " "Al Si P S Cl Ar " + "K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr " + "Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe " + "Cs Ba* Lu Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn " + "Fr Ra**" + + " *La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb " + " **Ac Th Pa U Np Pu "; +Cs C *Xe = "111%%d:\0\n"; +Cs C H[] = "22"; +Cs C U[] = "3"; +Cs I Zr = 0; +Cs I O = 1; +Cs I W = 2; + +V (*At)(V) = abort; +V (*F)(V *) = free; +V *(*Mo)(Si) = malloc; +I (*Pr)(Cs C *, ...) = printf; +I (*P)(I) = putchar; + +??= define Tm(B,C) Sc B { C *B; I N; } ; Te Sc B *B; B N##B (I) ; V F##B (B) ; C B##C (B, I) ; V C##B (B, I, C) ; B N##B (I N) { B B; Re (W, B = Mo(Si(Sc B))) ? (O, B->B = Mo(((W, B->N = N) ? N : O) * Si(C))) ? B Cl(: (At(), B)); } V F##B (B B) { F(B->B); F(B); } C B##C (B B, I N) { Re B->Nb ? B->B[N] : (C) Zr; } V C##B (B B, I N, C C) { N; B->Nb ? B->B[N] = C : C ? At(), C : C; } +Tm(B,C) + +V Pb (B) ; +I Bi (B) ; +C Co (B, B, I) ; +B Sb (B, I) ; + +V Pb (B B) { + I I; + Fr(Ba) + P(Ba); +} +I Bi (B B) { + I I; + Fr(Ba) ; + Re I; +} +C Co (B Br, B B, I N) { + I I; + Fr(I < N) + Ir(Be - Ba) + Re Be - Ba; + Re Zr; +} +B Sb (B Br, I N) { + B B; + I I; + + B = NB(Zn ? Bi(Br) + N : N); + FO(I = Zn ? -N : Zr; Zn ? Be : I < N; I++) + CB(B, Zn ? I + N : I, Be); + Re B; +} + +Tm(Br,B) + +V PBr (Br, I) ; + +V PBr (Br B, I N) { + I I, Rn=0; + Pr(W * W + Xe, N); + Fr(BrB(B, I)) { + P(O[Na]); + Pb(BrB(B, I)); + Ir(++Rn==Ag) Rn=0, P(Xe[W << W]); + } + P(Xe[W << W]); +} + +B Dy (B, I) ; +I S (C, B) ; +Br Sr (Br) ; + +B Dy (B Br, I N) { + B B; + C C, Cr; + II; + + B = NB(W * Bi(Br)); + FO(In = I = Zr; (O, C = Be); I++) { + FO(Cr = O; (W, C == BC(Br, I + Cr)); Cr++) ; + I += Cr - O; + Ca(++, Cr + Si(H)**H - Si(U)**U); + Ca(++, C); + } + Ir(N) + FB(Br); + Ca(-N, W[H]); + Re B; +} +I S (C C, B Br) { + B B, BF; + II; + + Ir(C == BC(Br, Zr)) + Re Zr; + + Fr(Be) { + B = Cl(BF = Sb(Br, I); ) + + Fe(BC(B, Zr)) { + B = Dy(B, W); + Ir(C == BC(B, Zr)) { + FF + Re Zr; + } + + Ir(In % W) + BF = Dy(BF, W); + + Ir(Zr == Co(B, BF, Bi(BF))) { + FF + Re O; + } + } + + FF + } + B = Dy(Br, Zr); + I = S(C, B); + FB(B); + Re I; +} +Br Sr (Br BrF) { + Br Br; + B B, BF; + II, N; + + FrB + N += Bi(B); + Br = NBr(N); + FrB { + Rb(N++, B); + Fe(BC(B, In + O)) + S(BC(B, In), BF = Sb(B, -In - O)) ? + Ca(+O, O[U]), + Rb(N++, B = BF), + In = Zr : + (FB(BF), W); + } + FBr(BrF); + Rb(N, (V *) Zr); + Re Br; +} + +I In (I, C **) ; + +I In (I N, C ** C) { + Br Br; + B B; + II; + + Br = NBr(--N); + Fr(I < N) { + FI ; + Rb(I, B = NB(In)); + FI + Ca(-Zr, IO); + } + + Fr(BrB(Br, Zr)) { + Br = Sr(Br); + PBr(Br, I); + + Fe((W, B = BrB(Br, In))) { + Rb(In, Dy(B, Zr)); + FB(B); + } + } + + { } { } { } { } { } { } { } { } { } { } { } +{ } { { } } { } { } { } { } { } { } { } { } { { } } +{ { } } { } { } { } { } { } { } { { } } { } { } { { } } C; +{ } { { } } { } { } { } { } { } { } { } { } { { } } + { } { } { } { } { } { } { } { } { } { } { } + + + + Re Zr; +} diff --git a/2004/jdalbec/try.alt.sh b/2004/jdalbec/try.alt.sh new file mode 100755 index 000000000..5b4a79495 --- /dev/null +++ b/2004/jdalbec/try.alt.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# try.alt.sh - demonstrate IOCCC winner 2004/jdalbec 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 + +# start out with default 11 +make clobber CC="$CC" alt >/dev/null || exit 1 + +# clear screen after compilation so that only the entry is shown +clear + +echo "$ ./jdalbec.alt 11 | head" 1>&2 +./jdalbec.alt 11 | head +echo 1>&2 + +read -r -n 1 -p "Press any key to continue: " +echo 1>&2 +echo "$ ./jdalbec.alt 47 | grep : | head -n 52572 | grep :" 1>&2 +./jdalbec.alt 47 | head -n 52572 | grep : +echo 1>&2 + +read -r -n 1 -p "Press any key to set 7 numbers per line: " +make clobber CC="$CC" CDEFINE="-DAg=7" alt >/dev/null || exit 1 + +echo "$ ./jdalbec.alt 101 | head" 1>&2 +./jdalbec.alt 101 | head +echo 1>&2 +read -r -n 1 -p "Press any key to continue: " + +echo 1>&2 +echo "$ ./jdalbec.alt 7 | grep : | head -n 47 | grep :" 1>&2 +./jdalbec.alt 7 | head -n 47 | grep : diff --git a/2004/jdalbec/try.sh b/2004/jdalbec/try.sh new file mode 100755 index 000000000..6a01edaaa --- /dev/null +++ b/2004/jdalbec/try.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# +# try.sh - demonstrate IOCCC winner 2004/jdalbec +# + +# 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 + +# start out with default 11 +make CC="$CC" all >/dev/null || exit 1 + +# clear screen after compilation so that only the entry is shown +clear + +echo "$ ./jdalbec 11 | head" 1>&2 +./jdalbec 11 | head +echo 1>&2 +read -r -n 1 -p "Press any key to continue: " +echo 1>&2 +echo "$ ./jdalbec 47 | grep : | head | grep :" 1>&2 +./jdalbec 47 | head | grep : +echo 1>&2 + +read -r -n 1 -p "Press any key to continue: " +echo 1>&2 +echo "$ ./jdalbec 1 | head" 1>&2 +./jdalbec 1 | head +echo 1>&2 + +read -r -n 1 -p "Press any key to continue: " +echo 1>&2 +echo "$ ./jdalbec 11 | head" 1>&2 +./jdalbec 11 | head +echo 1>&2 + +read -r -n 1 -p "Press any key to continue: " +echo "$ ./jdalbec 1 1 | head" 1>&2 +./jdalbec 1 1 | head diff --git a/bugs.md b/bugs.md index f6dda9b90..e981d28f6 100644 --- a/bugs.md +++ b/bugs.md @@ -2131,6 +2131,36 @@ The current ([Makefile](2004/gavin/Makefile) was modified to try and fit into the current IOCCC build environment. +## 2004 jdalbec + +### STATUS: INABIAF - please **DO NOT** fix +### Source code: [2004/jdalbec/jdalbec.c](2004/jdalbec/jdalbec.c) +### Information: [2004/jdalbec/README.md](2004/jdalbec/README.md) + +The author stated that: + +``` +Arguments matching `/[^2]22$/` cause the program to segfault +after rapidly exhausting the available stack space. I could +probably fix this by adding some special cases to the code, +but [Blaine the Mono] it's quite a bit more exciting this way, +don't you think?[/Blaine] Since the trailing `22` will be +its own atom anyway, you can just insert a space in front of +it if you run into this feature (e.g. `1 22` instead of `122`). + +Arguments matching `/(?:.){10,}/` will produce visually incorrect +results (e.g., generation 1 starting from 1111111111 will +print as `: 1`), but there's nothing interesting about these +arguments that can't be modeled using shorter runs of the same +symbol. + +Arguments matching `/(?:.){257,}/` may produce mathematically +incorrect results (e.g., generation 1 starting from a string +of 257 `1`s will be calculated as `11`); the remark from the +previous paragraph applies here also. +``` + + ## 2004 sds ### STATUS: INABIAF - please **DO NOT** fix diff --git a/thanks-for-fixes.md b/thanks-for-fixes.md index cd0786022..7af52f158 100644 --- a/thanks-for-fixes.md +++ b/thanks-for-fixes.md @@ -2754,6 +2754,14 @@ jdalbec.c:65:5: error: expected ';' before 'B' and various other problems. +Cody also added [alt code](2004/jdalbec/README.md#alternate-code) which allows +one to control how many numbers after the `:` to print before printing a +newline, so that one can see the output a bit better (though for lines that have +a lot of numbers this will be harder to see). + +Finally Cody added [try.sh](2004/jdalbec/try.sh) and +[try.alt.sh](2004/jdalbec/try.alt.sh) to demonstrate both versions. + ## [2004/kopczynski](2004/kopczynski/kopczynski.c) ([README.md](2004/kopczynski/README.md]))