Portable Self-Replicating C Contest

Kathryn Huxtable huxtable at kuhub.cc.ukans.edu
Sat Apr 8 10:15:03 AEST 1989


Jerry Schwarz <jss at ulysses.att.com> writes (through E-Mail):
> In article <4244 at kuhub.cc.ukans.edu> you write:
> >char a[] = "char a[] = %c%s%c; main() { printf( a, 34, a, 34 ); }"; main() {
> >printf( a, 34, a, 34 ); }

> Not portable.  The code for " does not have to be 34.

I answered with a variant of the following:

Aw....You're right, of course.  No one has pointed out that it doesn't
print a trailing newline, either.  Actually, Stan Switzer at
sjs at bellcore.whatever_it_is has made a study of what he calls "Quine"
programs.

He calls them Quine programs after Willard van Orman Quine, who said:
"Yields falsehood when preceded by itself in quotations," yields
falsehood when preceded by itself in quotations.

Stan had a program when he was a student here at KU (1981) which was
extremely clean.  It wasn't particularly terse, though.  I say clean,
because the method generalized to a program of arbitrary complexity.

-Kathryn Huxtable
huxtable at kuhub.cc.ukans.edu

Reconstructing from memory:

-------------------------  Cut here  -------------------------
/*
 *  Quine -- Self replicating program.
 *
 *  Just compile, link and go.
 *
 *  Written by Kathryn Huxtable, after a memory of a similar
 *  program written by Stan Switzer.
 */

#include <stdio.h>

char *first[] = {
        "/*",
        " *  Quine -- Self replicating program.",
        " *",
        " *  Just compile, link and go.",
        " *",
        " *  Written by Kathryn Huxtable, after a memory of a similar",
        " *  program written by Stan Switzer.",
        " */",
        "",
        "#include <stdio.h>",
        NULL
};

char *last[] = {
        "/*",
        " *  Print a vector of lines one line at a time.",
        " */",
        "",
        "print_norm( char *lines[] )",
        "{",
        "        int     i;",
        "",
        "        for( i = 0; lines[i] != NULL; i++ )",
        "                printf( \"%s\\n\", lines[i] );",
        "",
        "}       /*  print_norm  */",
        "",
        "",
        "/*",
        " *  Print a quoted string, enclosing it in quotes",
        " *  and escaping quote and backslash.",
        " */",
        "",
        "puts_quoted( char *str )",
        "{",
        "        int     i;",
        "",
        "        putchar( '\"' );",
        "",
        "        for( i = 0; str[i] != '\\0'; ++i ) {",
        "                if( str[i] == '\"' || str[i] == '\\\\' )",
        "                        putchar( '\\\\' );",
        "                putchar( str[i] );",
        "        }",
        "",
        "        putchar( '\"' );",
        "",
        "}       /*  puts_quoted  */",
        "",
        "",
        "/*",
        " *  Print a vector of lines, in the format",
        " *  in which it was declared.",
        " */",
        "",
        "print_quoted( char *name, char *lines[] )",
        "{",
        "        int     i;",
        "",
        "        printf( \"char *%s[] = {\\n\", name );",
        "",
        "        for( i = 0; lines[i] != NULL; i++ ) {",
        "                printf( \"        \" );",
        "                puts_quoted( lines[i] );",
        "                printf( \",\\n\" );",
        "        }",
        "",
        "        printf( \"        NULL\\n\" );",
        "        printf( \"};\\n\" );",
        "        printf( \"\\n\" );",
        "",
        "}       /*  print_quoted  */",
        "",
        "",
        "/*",
        " *  Print a copy of my source, reconstructed",
        " *  from the vectors first and last.",
        " */",
        "",
        "main()",
        "{",
        "        print_norm( first );",
        "        printf( \"\\n\" );",
        "        print_quoted( \"first\", first );",
        "        print_quoted( \"last\", last );",
        "        printf( \"\\n\" );",
        "        print_norm( last );",
        "",
        "}       /*  main  */",
        NULL
};


/*
 *  Print a vector of lines one line at a time.
 */

print_norm( char *lines[] )
{
        int     i;

        for( i = 0; lines[i] != NULL; i++ )
                printf( "%s\n", lines[i] );

}       /*  print_norm  */


/*
 *  Print a quoted string, enclosing it in quotes
 *  and escaping quote and backslash.
 */

puts_quoted( char *str )
{
        int     i;

        putchar( '"' );

        for( i = 0; str[i] != '\0'; ++i ) {
                if( str[i] == '"' || str[i] == '\\' )
                        putchar( '\\' );
                putchar( str[i] );
        }

        putchar( '"' );

}       /*  puts_quoted  */


/*
 *  Print a vector of lines, in the format
 *  in which it was declared.
 */

print_quoted( char *name, char *lines[] )
{
        int     i;

        printf( "char *%s[] = {\n", name );

        for( i = 0; lines[i] != NULL; i++ ) {
                printf( "        " );
                puts_quoted( lines[i] );
                printf( ",\n" );
        }

        printf( "        NULL\n" );
        printf( "};\n" );
        printf( "\n" );

}       /*  print_quoted  */


/*
 *  Print a copy of my source, reconstructed
 *  from the vectors first and last.
 */

main()
{
        print_norm( first );
        printf( "\n" );
        print_quoted( "first", first );
        print_quoted( "last", last );
        printf( "\n" );
        print_norm( last );

}       /*  main  */



More information about the Comp.std.c mailing list