2017년 6월 15일 목요일

쿠와인(프로그래밍)

쿠와인(프로그래밍)

쿠와인(: Quine)은, 컴퓨터 프로그램의 일종으로, 자신의 원시 코드와 완전하게 같은 문자열을 출력하는 프로그램이다.오락으로서 프로그래머가 임의의 프로그램 언어로의 최단 쿠와인을 쓰는 일이 있다.프로그램을 출력하는 프로그램이라고 보면, 쿠와인의 프로그래밍은 메타 프로그래밍의 일종이다.

입력을 받아들이는 프로그램은, 쿠와인이라고는 보여지지 않는다.입력이 허용 된다면, 단지 키보드로부터 원시 코드를 입력하는 것만으로 실현되어 버리고, 그 프로그램의 원시 파일을 입력으로 하는 등도 실현될 수 있다.실행 코드를 포함하지 않는 쿠와인도 자명하다라고 해 제외된다.많은 프로그램 언어로는, 실행 코드가 없는 프로그램은 코드를 분명하게 출력 가능(아무것도 없기 때문에, 아무것도 출력하지 않지는 쿠와인이라고 주장할 수 있다)이다.그러한 하늘의 프로그램이 IOCCC로 「규칙의 심한 악용」상을 수상했던 적이 있다.

쿠와인이라고 하는 명칭은, 자기 참조의 연구에 대하고 실적을 남긴 철학자 위라드・밴・오멘・쿠와인(1908-2000)에 유래해, 명명한 것은 더글라스・호후스탓타로 그만큼 낡은 것은 아니기 때문에, 낡은 문헌으로는 자기 복제・자기 재생성등이라고 하는 표현으로 불리고 있는 일이 있다.(프로그램 언어는 아니다) 언어적으로는 다음 일문으로 나타내지는 쿠와인의 파라독스와 같은 구조를 가지고 있다.

「 「은, 자신의 인용을 전치 되면 가짜가 된다」는, 자신의 인용을 전치 되면 가짜가 된다」

목차

역사

크리네의 재귀 정리로부터 직접 이끌리는 대로, 임의의 계산 가능한 문자열을 출력할 수 있는 프로그램 언어에는 쿠와인이 존재한다.이러한 쿠와인이라고 하는 발상을 최초로 볼 수 있던 것은, Bratley, Paul and Jean Millo. "Computer Recreations; Self-Reproducing Automata", Software -- Practice & Experience, Vol. 2 (1972). pp. 397-400. doi:10.1002/spe. 4380020411이었다.Bratley가 자기 복제 프로그램에 흥미를 가지게 된 것은, 에딘버러 대학의 강사켄 연구자 Hamish Dewar가 Atlas Autocode으로 쓴 프로그램을 보았던 것이 계기로 있었다.그 프로그램은 다음 대로이다.

 %BEGIN !THIS IS A SELF-REPRODUCING PROGRAM %ROUTINESPEC R R PRINT SYMBOL(39) R PRINT SYMBOL(39) NEWLINE %CAPTION %END~ %CAPTION %ENDOFPROGRAM~ %ROUTINE R %PRINTTEXT ' %BEGIN !THIS IS A SELF-REPRODUCING PROGRAM %ROUTINESPEC R R PRINT SYMBOL(39) R PRINT SYMBOL(39) NEWLINE %CAPTION %END~ %CAPTION %ENDOFPROGRAM~ %ROUTINE R %PRINTTEXT ' %END %ENDOFPROGRAM 

일반적으로, 임의의 프로그램 언어로 쿠와인을 쓰려면 , 프로그램내를 이하의 2개의 부분으로 나눈다.제일은, 출력을 실제로 실시하는 원시 코드, 제2는, 코드를 문자열로서 나타낸 데이터이다(예를 들면, 후술의 C언어의 예로의 progdata).코드는 데이터를 사용해 코드부 자신의 출력도 하지만(데이터의 내용이 원래 코드부를 텍스트 표현으로 한 것이기 위해, 이것이 가능해진다), 더 단순하게 데이터의 텍스트 표현도 출력한다.코드와 데이터를 프로그램내에서 구성하는 방법은 다양하지만, 데이터부의 공통된 특징으로서 데이터는 프로그램 전체가 있는 정도의 부분을 반영하고 있다. 원시 코드안에 자기 자신을 직접 묻으려고 하면 엔들레스 루프가 일어나 버리기 위해, 그것을 어떻게 회피할지가 포인트가 된다.

C언어

C언어로의 쿠와인의 예를 나타낸다.여기에서는, 코드를 문자열로서 격납하고 있어, 코드부와 문자열 자신의 2회의 출력을 실시한다.

 /* A simple quine (self-printing program), in standard C. */  /* Note: in designing this quine, we have tried to make the code clear  * and readable, not concise and obscure as many quines are, so that  * the general principle can be made clear at the expense of length.  * In a nutshell: use the same data structure (called "progdata"  * below) to output the program code (which it represents) and its own  * textual representation. */  #include <stdio.h>  void quote(const char *s)      /* This function takes a character string s and prints the       * textual representation of s as it might appear formatted       * in C code. */ {     int i;      printf("    \"");     for (i=0; s[i]; ++i) {         /* Certain characters are quoted. */         if (s[i] == '\\')             printf("\\\\");         else if (s[i] == '"')             printf("\\\"");         else if (s[i] == '\n')             printf("\\n");         /* Others are just printed as such. */         else             printf("%c", s[i]);         /* Also insert occasional line breaks. */         if (i % 48 == 47)             printf("\"\n    \"");     }     printf("\""); }  /* What follows is a string representation of the program code,  * from beginning to end (formatted as per the quote() function  * above), except that the string _itself_ is coded as two  * consecutive '@' characters. */ const char progdata[] =     "/* A simple quine (self-printing program), in st"     "andard C. */\n\n/* Note: in designing this quine, "     "we have tried to make the code clear\n * and read"     "able, not concise and obscure as many quines are"     ", so that\n * the general principle can be made c"     "lear at the expense of length.\n * In a nutshell:"     " use the same data structure (called \"progdata\"\n"     " * below) to output the program code (which it r"     "epresents) and its own\n * textual representation"     ". */\n\n#include <stdio.h>\n\nvoid quote(const char "     "*s)\n     /* This function takes a character stri"     "ng s and prints the\n      * textual representati"     "on of s as it might appear formatted\n      * in "     "C code. */\n{\n    int i;\n\n    printf(\"    \\\"\");\n "     "   for (i=0; s[i]; ++i) {\n        /* Certain cha"     "racters are quoted. */\n        if (s[i] == '\\\\')"     "\n            printf(\"\\\\\\\\\");\n        else if (s["     "i] == '\"')\n            printf(\"\\\\\\\"\");\n        e"     "lse if (s[i] == '\\n')\n            printf(\"\\\\n\");"     "\n        /* Others are just printed as such. */\n"     "        else\n            printf(\"%c\", s[i]);\n   "     "     /* Also insert occasional line breaks. */\n "     "       if (i % 48 == 47)\n            printf(\"\\\"\\"     "n    \\\"\");\n    }\n    printf(\"\\\"\");\n}\n\n/* What fo"     "llows is a string representation of the program "     "code,\n * from beginning to end (formatted as per"     " the quote() function\n * above), except that the"     " string _itself_ is coded as two\n * consecutive "     "'@' characters. */\nconst char progdata[] =\n@@;\n\n"     "int main(void)\n     /* The program itself... */\n"     "{\n    int i;\n\n    /* Print the program code, cha"     "racter by character. */\n    for (i=0; progdata[i"     "]; ++i) {\n        if (progdata[i] == '@' && prog"     "data[i+1] == '@')\n            /* We encounter tw"     "o '@' signs, so we must print the quoted\n       "     "      * form of the program code. */\n        {\n "     "           quote(progdata);    /* Quote all. */\n"     "            i++;                /* Skip second '"     "@'. */\n        } else\n            printf(\"%c\", p"     "rogdata[i]);  /* Print character. */\n    }\n    r"     "eturn 0;\n}\n";  int main(void)      /* The program itself... */ {     int i;      /* Print the program code, character by character. */     for (i=0; progdata[i]; ++i) {         if (progdata[i] == '@' && progdata[i+1] == '@')             /* We encounter two '@' signs, so we must print the quoted              * form of the program code. */         {             quote(progdata);    /* Quote all. */             i++;                /* Skip second '@'. */         } else             printf("%c", progdata[i]);  /* Print character. */     }     return 0; } 

이제 1개의 예는, C의 프리프로세서를 사용한 것이다.

 #include <stdio.h> int main(int argc, char** argv) { #define B(x) x; printf("  B(" #x ")\n"); #define A(x) printf("  A(" #x ")\n"); x;   B(printf("#include <stdio.h>\nint main(int argc, char** argv)\n{\n#define B(x)      x; printf(\"  B(\" #x \")\\n\");\n#define A(x) printf(\"  A(\" #x \")\\n\"); x;\n"))   A(printf("}\n")) } 

이 예로는, B(printf(로 시작되는 행은 다음 행으로 연결되고 있다(보기 쉽게하기 위해(때문에) 2행으로 표시했다). argv)\n{\n#define B(x)와 x;의 사이에는 공백이 1개있다.

프로 프로세서를 사용하지 않고 , printf 함수를 이용해 주의 깊고 서식 문자열과 치환 파라미터를 배치하는 것으로, 한층 더 짧은 프로그램을 쓸 수도 있다.이하의 예로, 34라고 하는 것은 더블 쿼츠 문자의 ASCII 코드이며, 문자열 리터럴내의 더블 쿼츠를 인용할 필요를 막기 위해서 사용되고 있다.

 int main() { char *s = "int main() { char *s = %c%s%c; printf(s, 34, s, 34); }"; printf(s, 34, s, 34); } 

Scheme

Scheme으로의 예.Common Lisp라고 해도 타당한 예가 되고 있다.이 쿠와인으로는 프로그램 자신을 입력으로 해, 데이터 구조로부터 원시 코드에의 변환을 한다.

 ((lambda (x) (list x (list 'quote x)))  '(lambda (x) (list x (list 'quote x)))) 

MS-Office VBA(매크로)

MS-Office VBA(매크로)의 예. 이미디에이트윈드우에 직접 입력 가능한 이 가벼운 놀이의 예는, 고의로 밤가독성 저하・장황한 장식을 포함해, 코드가 전후 동형이 되어 있다.

 :i="&chr(34):?mid(i,34);i;mid(i,1,34):i="&chr(34):?mid(i,34);i;mid(i,1,34): 

Haskell

Haskell으로의 예.Haskell에는 값을 그 표현으로 변환하는 show 함수가 갖춰지고 있기 때문에 간단하게 실장할 수 있다.

 main = putStrLn $ q ++ show q where q = "main = putStrLn $ q ++ show q where q = " 


관련 항목

참고 문헌

외부 링크

This article is taken from the Japanese Wikipedia 쿠와인(프로그래밍)

This article is distributed by cc-by-sa or GFDL license in accordance with the provisions of Wikipedia.

Wikipedia and Tranpedia does not guarantee the accuracy of this document. See our disclaimer for more information.

In addition, Tranpedia is simply not responsible for any show is only by translating the writings of foreign licenses that are compatible with CC-BY-SA license information.

0 개의 댓글:

댓글 쓰기