leo@s514.ipmce.su (Leonid A. Broukhis) (03/11/91)
This is an introspective program in C. char*a="char*a=%c%s%c;main(){printf(a,34,a,34);}";main(){printf(a,34,a,34);} Do you know a shorter program? -- Leonid A. Broukhis | 89-1-95 Liberty St. | "BROUKHIS" is Hebrew for 7+095 494.6241 (h) | Moscow 123481 USSR | "BENEDICTAE" 7+095 132.9475 (o) | (leo@s514.ipmce.su) | {Licet omnia qualibet dicas}
olsen@casbah.acns.nwu.edu (Jeff Olsen) (03/11/91)
In article <AB2MbsdCB6@s514.ipmce.su> leo@s514.ipmce.su writes: > This is an introspective program in C. >char*a="char*a=%c%s%c;main(){printf(a,34,a,34);}";main(){printf(a,34,a,34);} > Do you know a shorter program? sure... *a="*a=%c%s%c;main(){printf(a,34,a,34);}";main(){printf(a,34,a,34);} I tried it with MSC 6.0 and whatever the default cc is on a encore multimax. GCC doesn't appear to like it, though. Jeff Olsen olsen@eecs.nwu.edu
andy@research.canon.oz.au (Andy Newman) (03/12/91)
The smaller the better! In many interpreted BASIC's of years ago you could do: 1 LIST Which when RUN would produce: 1 LIST (Using a single digit line number to make it as small as possible). -- Andrew Newman, Software Engineer. | Net: andy@research.canon.oz.au Canon Information Systems Research Australia | Phone: +61 2 805 2914 P.O. Box 313 North Ryde, NSW, Australia 2113 | Fax: +61 2 805 2929
scotth@corp.sgi.com (Scott Henry) (03/12/91)
andy> The smaller the better! In many interpreted BASIC's of years ago you andy> could do: andy> 1 LIST andy> Which when RUN would produce: andy> 1 LIST andy> (Using a single digit line number to make it as small as possible). And in any sh|csh|tcsh on unix, this one is about as short as you can get: cat $0 -- Scott Henry <scotth@sgi.com> / Traveller on Dragon Wings Information Services, / Help! My disclaimer is missing! Silicon Graphics, Inc / Politicians no baka!
jonth@ifi.uio.no (Jon Thingvold) (03/13/91)
What about this one (BSD UNIX): #!/bin/cat Or better in SIMULA an empty file is a valid program that (of course) produces no output. Jon. --
dm@think.com (Dave Mankins) (03/13/91)
This is not quite the same thing, but it is a hack I have found very useful
when spinning small test programs.
You start the program (e.g., ``foo.c'') with:
#ifdef notdef
cc $0 -g -o `basename $0 .c` -Ineeded-includes -lneeded-libraries
exit;
#endif notdef
#include <stdio.h>
...
(all bound to an emacs function, insert-self-compile, of course)
Then invoke it with:
sh foo.c
This is much less labor-intensive than editing a Makefile (and re-editing it,
if the source file should move to another directory).
Even in semi-formally maintained code, I have found this most useful in files
that make up components of libraries, in this form:
#ifdef notdef
cc $0 -DTEST -g -o `basename $0 .c` -Ineeded-includes -lneeded-libraries
exit;
#endif notdef
/* library module source ... */
#ifdef TEST
main() {
.... code to test the call library functions with test inputs and
check the results ....
}
#endif /* TEST */
This allows your library modules to be self-testing, a great time-saver in the
later phases of development.
--
david mankins (dm@think.com)
clear@cavebbs.gen.nz (Charlie Lear) (03/13/91)
In article <1991Mar12.050929.2870@research.canon.oz.au> andy@research.canon.oz.au (Andy Newman) writes: >The smaller the better! In many interpreted BASIC's of years ago you could do: > 1 LIST >Which when RUN would produce: > 1 LIST >(Using a single digit line number to make it as small as possible). Sorry, your entry is disqualified through being too large. REAL BASICs used to be able to tokenise, and the winner is: 1 L. which when run would produce 1 L. Lets see you do THAT in C! -- -------------------------------------------------------------------------- Charlie "The Bear" Lear | clear@cavebbs.gen.nz | Kawasaki Z750GT DoD#0221 The Cave MegaBBS +64 4 642260 V32 | PO Box 2009, Wellington, New Zealand --------------------------------------------------------------------------
steele@en.ecn.purdue.edu@en.ecn.purdue.edu (Richard A. Steele) (03/13/91)
In article <1991Mar13.032422.9438@cavebbs.gen.nz> clear@cavebbs.gen.nz (Charlie Lear) writes: >In article <1991Mar12.050929.2870@research.canon.oz.au> andy@research.canon.oz.au (Andy Newman) writes: >>The smaller the better! In many interpreted BASIC's of years ago you could do: >> 1 LIST >>Which when RUN would produce: >> 1 LIST >>(Using a single digit line number to make it as small as possible). > >Sorry, your entry is disqualified through being too large. REAL BASICs used >to be able to tokenise, and the winner is: > 1 L. >which when run would produce > 1 L. > >Lets see you do THAT in C! > You sure? If the BASIC is tokenized, then L. will be expanded to LIST in the source code listing, so that you'd get 1 LIST when run. I have to admit, my only experience with tokenized basics is the old 8-bit Ataris; do other basics leave the abbreviation? Rich -- ------------------------------------------------------------------------------- Richard Steele | INTERNET : steele@ecn.purdue.edu Electrical Engineering | BITNET : steele%ecn.purdue.edu@purccvm Purdue University | UUCP : {purdue, pur-ee}!ecn.purdue.edu!steele
henry@zoo.toronto.edu (Henry Spencer) (03/14/91)
In article <1991Mar13.001423.5194@Think.COM> dm@think.com (Dave Mankins) writes: >You start the program (e.g., ``foo.c'') with: > >#ifdef notdef > cc $0 -g -o `basename $0 .c` -Ineeded-includes -lneeded-libraries > exit; >#endif notdef It is no longer legal to put arbitrary trash after "#endif", so that identifier has to go. "#endif /* notdef */" is better. Note also that you need to be careful about what you put inside #ifdef, because it is *not* completely ignored. The above example should be okay, but in general the contents have to be either legal C tokens or things that could not be mistaken for C tokens. Notably, an unmatched ' or " is not kosher. -- "But this *is* the simplified version | Henry Spencer @ U of Toronto Zoology for the general public." -S. Harris | henry@zoo.toronto.edu utzoo!henry
zap@savage.UUCP (Zap Savage) (03/14/91)
In <1991Mar13.151756.2885@en.ecn.purdue.edu>, steele@en.ecn.purdue.edu@en.ecn.purdue.edu (Richard A. Steele) writes: > In article <1991Mar13.032422.9438@cavebbs.gen.nz> clear@cavebbs.gen.nz (Charlie Lear) writes: > > REAL BASICs used > >to be able to tokenise, and the winner is: > > 1 L. > >which when run would produce > > 1 L. > You sure? If the BASIC is tokenized, then L. will be expanded to LIST > in the source code listing, so that you'd get > 1 LIST > when run. I have to admit, my only experience with tokenized basics is > the old 8-bit Ataris; do other basics leave the abbreviation? Nah, old TRS-80s with Level-1 Basic stored exactly what you typed and L. was indeed the short form of LIST as P. was short for PRINT. 1 L. would indeed work. Zap --- Zap Savage, Savage Research, Inc. "We are the energy of Shakespeare's verse/we are what mathematics wants to be/ The Life Force in the Universe/That longs to See!/That would Become/and give a voice to matter that was dumb." "To Sail Beyond The Sun" R. Bradbury&J.V.Post
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (03/14/91)
The subject line is seriously misleading. None of the examples that has been posted has anything to do with INTROSPECTION (one might call 3-Lisp introspective, perhaps even Scheme, with its built in function call-with-current-continuation). They are SELF-REPRODUCING programs, which is something rather different. A program would be introspective if it could take a step back from itself and watch its own workings. (One might even call a UNIX program that has called monitor() or profil() an introspective program.) Self-reproducing programs are old hat. -- The purpose of advertising is to destroy the freedom of the market.
magnus%thep.lu.se@Urd.lth.se (Magnus Olsson) (03/14/91)
In article <1991Mar13.151756.2885@en.ecn.purdue.edu> steele@en.ecn.purdue.edu@en.ecn.purdue.edu (Richard A. Steele) writes: >In article <1991Mar13.032422.9438@cavebbs.gen.nz> clear@cavebbs.gen.nz (Charlie Lear) writes: >>Sorry, your entry is disqualified through being too large. REAL BASICs used >>to be able to tokenise, and the winner is: >> 1 L. >>which when run would produce >> 1 L. >You sure? If the BASIC is tokenized, then L. will be expanded to LIST >in the source code listing, so that you'd get > 1 LIST >when run. I have to admit, my only experience with tokenized basics is >the old 8-bit Ataris; do other basics leave the abbreviation? I'm afraid Charlie used the word `tokenize' in a non-canonical way... Tokenization means that tokens (identifiers, keywords etc) are saved just as numbers, not as text. The interpreter would recognize `L.' as a valid abbreviation of LIST, and store the corresponding number. The LIST command would then look up this number and write out the corresponding word, i.e. `LIST'. Applesoft Basic did this, I believe - `?' was accepted as an abbreviation for `PRINT', but the LIST command printed it as `PRINT'. Anyway, there *are* Basics that don't tokenize, but accept abbreviated statements - like the one on the Acorn Atom (a 6502-based British machine). A typical line from an Atom program would look something like 100F.I=1TOA.X;P.ZZX';GOS.200;N. which would correspond to 100 FOR I=1 TO ABS(X) : PRINT ZZ(X) : GOSUB 200 : NEXT I in Micrososft Basic. Unfortunately, Atom Basic didn't allow LIST inside a program, so Charlie's program wouldn't run on an Atom... Magnus Olsson | \e+ /_ Dept. of Theoretical Physics | \ Z / q University of Lund, Sweden | >----< Internet: magnus@thep.lu.se | / \===== g Bitnet: THEPMO@SELDC52 | /e- \q
jay@hermix.UUCP (Jay Skeer) (03/16/91)
This one is self-recognizing. I am sure someone can do it shorter. (Btw, what about lisp's shortest self-repro programs "T", "0", "1", "2", ...) j' ------------------- #include <stdio.h> #define N 18 #define F 8 #define L 80 #define Y Z[k++] #define P sprintf char*I="\"%s\",",*B="%s", M[N*3][L],Z[L],D[N][L]={ "#include <stdio.h>", "#define N 18", "#define F 8", "#define L 80", "#define Y Z[k++]", "#define P sprintf", "char*I=\"\\\"%s\\\",\",*B=\"%s\",", "M[N*3][L],Z[L],D[N][L]={", "\"\"},v='\\\\',q='\\\"';", "main(){int c,i=0,j=0,k,l;", "for(;i<F;P(M[j++],B,D[i++]));", "for(i=0;i<N-1;i++,P(M[j++],I,Z))", "for(k=0,l=0;Z[k]=0,c=D[i][l++];Y=c)", "((c^v)*(c^q))||(Y=v);", "for(i=F;i<N;P(M[j++],B,D[i++]));", "for(i=0;gets(Z);)strcmp(M[i++],Z)&&exit(puts(\"no\"),1);", "exit(puts(\"yes\"),0);}", ""},v='\\',q='\"'; main(){int c,i=0,j=0,k,l; for(;i<F;P(M[j++],B,D[i++])); for(i=0;i<N-1;i++,P(M[j++],I,Z)) for(k=0,l=0;Z[k]=0,c=D[i][l++];Y=c) ((c^v)*(c^q))||(Y=v); for(i=F;i<N;P(M[j++],B,D[i++])); for(i=0;gets(Z);)strcmp(M[i++],Z)&&exit(puts("no"),1); exit(puts("yes"),0);}
jay@hermix.UUCP (Jay Skeer) (03/16/91)
>I said: >This one is self-recognizing. I am sure someone can do it shorter. > Well, matter of fact, *I* can. Paste the folowing lines together into one line. No spaces. j' -- start cutting and pasting on the next line -- *a="*a=%c%s%c,b[256],c[256],q=34;main(){sprintf(b,a,q,a,q,q,q,q,q);get s(c);puts(strcmp(b,c)?%cno%c:%cyes%c);}",b[256],c[256],q=34;main(){spr intf(b,a,q,a,q,q,q,q,q);gets(c);puts(strcmp(b,c)?"no":"yes");}
rdc@nebulus.ampr.org (Dalton Clark) (03/17/91)
magnus%thep.lu.se@Urd.lth.se (Magnus Olsson) writes: >In article <1991Mar13.151756.2885@en.ecn.purdue.edu> steele@en.ecn.purdue.edu@en.ecn.purdue.edu (Richard A. Steele) writes: >>In article <1991Mar13.032422.9438@cavebbs.gen.nz> clear@cavebbs.gen.nz (Charlie Lear) writes: >>>Sorry, your entry is disqualified through being too large. REAL BASICs used >>>to be able to tokenise, and the winner is: >>> 1 L. >>>which when run would produce >>> 1 L. >>You sure? If the BASIC is tokenized, then L. will be expanded to LIST >>in the source code listing, so that you'd get >> 1 LIST >>when run. I have to admit, my only experience with tokenized basics is Isn't there a BASIC that uses "!" as a REM. Thus the "shortest" basic program would be "1!"; this is 1/3 to 1/2 as short as your suggested "1 L." (I would have ommited the space before submitting). I believe it is an old Tandy basic that does this and it did not expand the "!" to rem but left it as is; it did add a space though .....
goer@quads.uchicago.edu (Richard L. Goerwitz) (03/18/91)
>Isn't there a BASIC that uses "!" as a REM. >Thus the "shortest" basic program would be "1!"; this is 1/3 to 1/2 as short >as your suggested "1 L." (I would have ommited the space before submitting). >I believe it is an old Tandy basic that does this and it did not expand the "!" >to rem but left it as is; it did add a space though ..... I don't see any source code here. Please note the followup-to line above. Please, please, please - ! -Richard
diamond@jit345.swstokyo.dec.com (Norman Diamond) (03/18/91)
In article <1991Mar17.190756.29382@midway.uchicago.edu> goer@quads.uchicago.edu (Richard L. Goerwitz) writes: >>Isn't there a BASIC that uses "!" as a REM. >>Thus the "shortest" basic program would be "1!"; this is 1/3 to 1/2 as short >>as your suggested "1 L." (I would have ommited the space before submitting). >>I believe it is an old Tandy basic that does this and it did not expand the "!" >>to rem but left it as is; it did add a space though ..... > >I don't see any source code here. Please note the followup-to line >above. Please, please, please - ! His source, though incorrect, is: 1! Therefore I have changed the follow-up back to alt.sources. Meanwhile, the reason his source is incorrect is that when you RUN it, it does not output a copy of itself. I still prefer the correct program which is even two characters shorter than that. (The source code is here, though it is difficult to see.) -- Norman Diamond diamond@tkov50.enet.dec.com If this were the company's opinion, I wouldn't be allowed to post it.
lee@sq.sq.com (Liam R. E. Quin) (03/21/91)
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes: >[About the hack for including a command to compile itself in a C program.] > Many years ago Tom Duff wrote a nifty little program called "com"; [...] I still use a shell-script called "use" for troff files, and sometimes for complex shell scripts. It understands a number of comment conventions, and looks for <any-sort-of-comment> use <command> A % sign is turned into the filename. For example, .\" Use pic % | troff - Options other than -n are passed along....and appear immediately before the first option in the Use line, so use -Timpr file in the above file would be turned into pic file | troff -Timpr - The Use comment must be in the 1st 5 lines. Personally I prefer make, but that's another story... Here it is. Edit the "sed" line to change "^G" into a control G before extracting. Lee sed 's/ControlG/^Gg' << 'boy' > use : if [ x"$1" = x"-n" ] then NOACTION=yes; shift fi while [ $# -gt 0 ] do case "$1" in -*) TSOPTS="$TSOPTS '$1'" shift ;; *) break ;; esac done FILE=${1-:"You must give a filename"} CMD=`sed -n '/^[ ]*[#%*;][#%!*;]*\([ ]*[uU]se \)/s//.\\\\" \1/ /^\.[ ]*\\\\"[ ]*[uU]se /p 5q' "${FILE}"` if [ x"$CMD" = x"" ] then echo "No Use comment in the file... do it yourself" exit 1 fi pipeline=`echo "$CMD" | sed -e ' s/^\.[ ]*\\\\"[ ]*[uU]se[ ]*// sControlG%'"ControlG${FILE}"'ControlGg sControlG -ControlG'"${TSOPTS}"'&ControlG ' ` echo $pipeline if [ x"$NOACTION" = x"yes" ] then echo "[no action taken]" else eval $pipeline fi use echo extracted use. exit 0 -- Liam R. E. Quin, lee@sq.com, SoftQuad Inc., Toronto, +1 (416) 963-8337 `A wrong that cannot be repaired must be transcended' Ursula K. Le Guin, in _Tehanu_
ishpanta@bluemoon.uucp (John Huenefeld) (03/22/91)
> Isn't there a BASIC that uses "!" as a REM. > > Thus the "shortest" basic program would be "1!"; this is 1/3 to 1/2 as short > your suggested "1 L." (I would have ommited the space before submitting). > > I believe it is an old Tandy basic that does this and it did not expand the " > to rem but left it as is; it did add a space though ..... I also believe that the Basic on the IBM system 3x machines (34,36,38) also uses the ! as REM. Also when listed it would be listed as 1 ! (even when you just typed 1!). John Huenefeld