Python
Perl
C
C#
quine

不動点プログラムの紹介

はじめに

本稿では不動点プログラムについて紹介します。

不動点プログラムとは何か

プログラムを実行すると、そのプログラムのソースコードがそのまま出力にされる、そのようなプログラムのことを不動点プログラムと呼びます。クワイン(quine)とも呼ばれます。
なお、この説明から推測されるように実用性はまったくありませんが、プログラミングの練習題材として扱われることがあります。

Python版

chr組み込み関数を使って、Unicodeコードポイントから文字を生成しているのがポイントです。34が二重引用符(")、10が改行(LF)を表します。

s = "s = {0}{2}{0}{1}print(s.format(chr(34), chr(10), s))"
print(s.format(chr(34), chr(10), s))
# python3 quine.py
s = "s = {0}{2}{0}{1}print(s.format(chr(34), chr(10), s))"
print(s.format(chr(34), chr(10), s))

Perl版

printf関数の書式指定を利用しています。39は一重引用符(')、10が改行(LF)を表します。Perlでは二重引用符で囲むと、変数展開されてしまうので、変数sを一重引用符で囲んでいるところがポイントです。

$s = '$s = %c%s%c;%cprintf($s, 39, $s, 39, 10);';
printf($s, 39, $s, 39, 10);
# perl quine.pl
$s = '$s = %c%s%c;%cprintf($s, 39, $s, 39, 10);';
printf($s, 39, $s, 39, 10);

C#版

class Quine{static void Main(){string s = "class Quine{0}static void Main(){0}string s = {1}{3}{1};System.Console.WriteLine(s, (char)123, (char)34, (char)125, s);{2}{2}";System.Console.WriteLine(s, (char)123, (char)34, (char)125, s);}}

少し見づらいので整形したコードを以下に示します。
やっていることはPython版と同じです。C#の場合、charでキャストすると数値から文字に変換できます。

class Quine
{
    static void Main()
    {
        string s = "class Quine{0}static void Main(){0}string s = {1}{3}{1};System.Console.WriteLine(s, (char)123, (char)34, (char)125, s);{2}{2}";
        System.Console.WriteLine(s, (char)123, (char)34, (char)125, s);
    }
}

C言語版

#include <stdio.h>
char *s = "#include <stdio.h>%cchar *s = %c%s%c; int main(void){ printf( s, 10, 34, s, 34 );return 0; }"; int main(void){ printf( s, 10, 34, s, 34 );return 0; }

少し見づらいので整形したコードを以下に示します。

#include <stdio.h>

char *s = "#include <stdio.h>%cchar *s = %c%s%c; int main(void){ printf( s, 10, 34, s, 34 );return 0; }"; 

int main(void)
{ 
    printf( s, 10, 34, s, 34 );
    return 0; 
}

おわりに

自分が使ったことある言語を使って、不動点プログラムを作ってみると、息抜きになっておすすめです。