【プログラム クイズ】

Codepad(http://codepad.org/)を使って
「自分自身を出力するプログラム」を作ってみて下さい。


つまり、ソースと出力結果が同じになるプログラムです。
言語はCodepadで使用可能な言語であればどれでも構いません。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2011/02/23 18:35:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答11件)

id:imo758 No.1

回答回数121ベストアンサー獲得回数19

ポイント15pt

http://codepad.org/CgFGPB8O

とりあえず完成速度第一に考えたのでひねりなくてすいません

@a=<DATA>;
print @a;
print "__DATA__\n";
print @a;
__DATA__
@a=<DATA>;
print @a;
print "__DATA__\n";
print @a;
id:garyo

ありがとうございます。

言語はPerlですね。

2011/02/22 11:08:11
id:practicalscheme No.2

回答回数157ベストアンサー獲得回数42

ポイント15pt

ちょっと変化球。Schemeだけど処理系依存あり: http://codepad.org/V2GaSgfk

Gaucheでは上のを走らせると出力が止まらないので注意。かわりにこれを: #0=(write/ss '#0#)

id:garyo

ありがとうございます。

いろいろな言語が出てきて嬉しいです。

2011/02/22 11:10:03
id:snmp No.3

回答回数20ベストアンサー獲得回数1

ポイント15pt

perlで書いてみました。

($0で自身のファイル名を取得)

#!/usr/bin/perl

use strict;
use warnings;

open(FILE,"<$0");
while(my $line = <FILE>){
 chomp $line;
 print $line."\n";
}
exit;
id:garyo

ありがとうございます。

Codepadで動くのかなと思って試してみたらちゃんと動きました。

サーバー上でのファイル名を取得するんですね。

2011/02/22 11:11:49
id:yossiy7 No.4

回答回数778ベストアンサー獲得回数96

ポイント15pt

// もしも引数が指定できるならそこに吐き出します

// 引数なしならそこに標準出力で出力します

#include <stdio.h>

int main(int argc, char *argv[])

{

char buf[4096];

FILE *rfd = fopen(__FILE__,"r");

FILE *wfd;

if( argc == 2 ) {

wfd = fopen( argv[1], "w" );

if( !wfd )

{

printf("Error! %s cannot output path\n", argv[1] );

return 1;

}

} else {

wfd = stdout;

}

while( fgets(buf,sizeof(buf),rfd ) ) {

fprintf(wfd,"%s",buf);

}

fclose(wfd);

fclose(rfd);

}

id:garyo

ありがとうございます。

c言語版ですね。

2011/02/22 11:14:54
id:tyne No.5

回答回数1ベストアンサー獲得回数0

ポイント15pt

Pythonでかいてみました。

ソース:

import os

path = os.path.abspath(__file__)

for line in open(path):

print line

リンク:Python code by yoshiyukiohta - 4 lines - codepad

id:garyo

ありがとうございます。

ファイルをソースにする方が多いですね。

2011/02/22 11:15:56
id:MAS3 No.6

回答回数40ベストアンサー獲得回数2

ポイント15pt

Perlです。

http://codepad.org/IkPKxyRk

id:garyo

ありがとうございます。

ファイルをソースに使うと短くなりますね。

2011/02/22 11:35:21
id:Mook No.7

回答回数1314ベストアンサー獲得回数393

ポイント15pt

先のはほとんど検索依存だったので、こちらが自作回答です。

>|c|

#include<stdio.h>

void main(){

char*s="\\\n\""

"#include<stdio.h>%cvoid main(){%cchar*s=%c%c%c%cn%c%c%c%s%c;%cprintf(s+3,s[1],s[1],s[2],*s,*s,*s,*s,s[2],s[2],s+1,s[2],s[1],s[1]);%c}";

printf(s+3,s[1],s[1],s[2],*s,*s,*s,*s,s[2],s[2],s+1,s[2],s[1],s[1]);

}

||<

http://codepad.org/8Jj5HVrY


仕組みはやはりほとんど一緒になってしまうので、目新しくはないですが、

だいたい1行のものが多かったので、改行を入れる部分を工夫してみました。


この次の段階となると、Wiki の C サンプルのように解析型になってしまいそうです。

http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AF%E3%82%A4%E3%83%B...

id:garyo

ありがとうございます。

これはまた複雑になりましたね。

2011/02/22 11:17:45
id:sheile No.8

回答回数45ベストアンサー獲得回数16

ポイント15pt

Rubyです。

http://codepad.org/Xv6kQEdA

print open($0).read
id:garyo

ありがとうございます。

面白いですね。

2011/02/22 18:27:55
id:ita No.9

回答回数204ベストアンサー獲得回数48

ポイント15pt

Mookさんのと方針は同じです。何をやってるか分かるようにしてみました。

不完全性定理の証明のときにこういうの使いますね。

http://codepad.org/JxVo0ZzP

#define p(c) putchar(c)
void pr(char *x, int f)
{
 char *y;
 for(y=x;*y;y++)
 {
  if(!f){p(*y);continue;}
  if(*y==0x58) {p(34);pr(x,0);p(34);}
  else if(*y==0x40)p(10);
  else p(*y);
 }
}
char *this="#define p(c) putchar(c)@void pr(char *x, int f)@{@ char *y;@ for(y=x;*y;y++)@ {@  if(!f){p(*y);continue;}@  if(*y==0x58) {p(34);pr(x,0);p(34);}@  else if(*y==0x40)p(10);@  else p(*y);@ }@}@char *this=X;@@void main(){pr(this,1);}@";

void main(){pr(this,1);}
id:garyo

ありがとうございます。

2011/02/23 09:00:47
id:karupanerura No.10

回答回数1ベストアンサー獲得回数0

ポイント15pt

[C]

http://codepad.org/kJ9HXGuK

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

[Perl]

http://codepad.org/Naj8yl7b

my @a = ();@a = qw(print 'my @a = ();@a = '."qw(@a); @a;"); print 'my @a = ();@a = '."qw(@a); @a;";
id:Mook No.11

回答回数1314ベストアンサー獲得回数393

ポイント10pt

インチキ回答ですので、ポイントは不要です。


下記のオリジナルは int でしたが、それではこのサイトではエラーが出るのでエラーが出ないように変更しました。

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

http://codepad.org/F6wuB7hZ


頑張ってオリジナルを作って見ようとしましたが、断念。フェイクです。

  • PHP
function quine() { s = "function quine() { s = %c%s%c; printf(s, 34, s, 34); }"; printf(s, 34, s, 34); }

http://codepad.org/2oAmEc1i


えーい、ここまでくればとことん。

以下、いろいろな言語のバージョンです。

  • Phython
#!/usr/bin/python
s = "#!/usr/bin/python%cs = %c%s%c%cprint s %% (10, 34, s, 34, 10)"
print s % (10, 34, s, 34, 10)

http://codepad.org/FxrWyLvA


  • C++
int main() { char s[] = "int main() { char s[] = %c%s%c; printf(s, 34, s, 34); }"; printf(s, 34, s, 34); }

http://codepad.org/OsMk9m9n

出典:http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AF%E3%82%A4%E3%83%B...


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

http://codepad.org/M7D2nr5f


以下自分では書けなかったので、検索で探したものです。

  • Haskell
main = putStr (s ++ [';',' ','s',' ','=',' '] ++ show s); s = "main = putStr (s ++ [';',' ','s',' ','=',' '] ++ show s)"

http://codepad.org/Jei65bSd

出典:http://www.iis.sinica.edu.tw/~scm/2007/a-haskell-quine/


  • Lua
s=[[io.write('s=[','[',s,']','];',s)]];io.write('s=[','[',s,']','];',s)

http://codepad.org/eA8QIIo1

出典:http://lua-users.org/lists/lua-l/2008-05/msg00364.html


  • Tcl
#! /usr/bin/env tclsh

proc Quine {} {
   puts {#! /usr/bin/env tclsh}
   puts {}
   puts -nonewline "proc Quine {} {"
   puts -nonewline [info body Quine]
   puts "}"
   puts ""
   puts "Quine"
 }

Quine

http://codepad.org/ZdGC2ZsK




なんてのをいろいろ探したり考えているうちにこんなのを見つけました。

http://d.hatena.ne.jp/ku-ma-me/20090916/p1

これはこのプログラム自身を出力する Unlambda プログラム、を出力する Whitespace プログラム、
 を出力する brainfuck プログラム、を出力する Java プログラム、を出力する C プログラム、
 を出力する Haskell プログラム、を出力する OCaml プログラム、を出力する Lua プログラム、
 を出力する Perl プログラム、を出力する Python プログラム、を出力する Ruby プログラム、です。

だそうです。

残念ながら Codepad では動きませんでしたが、脱帽です。


現在自作回答作成中ですが、締め切りまでに間に合うかな・・・。

  • id:yossiy7
    書くのを忘れていた気がしたので……
    自分のはC言語です。
  • id:garyo
    解答はソースだけでしょうか?
    Codepadで書いて実行してその結果のリンクを貼ってもらうのを想定していました。
  • id:yossiy7
    はい。
    このクイズの為にわざわざアカウント取得したくなかったので。
  • id:practicalscheme
    あれ、アカウント無しでもコード書けましたよ?
  • id:garyo
    私もユーザー登録なしで使っていました。
    ……というかloginできること自体に気がついていませんでした(^^;)
  • id:SuperSonics
    cool!
  • id:yossiy7
    >practicalscheme さん
    コードは書けます。
    その後、save this code をクリックすると、アカウント入力orアカウント作成しろ、という画面になります。
    だからgyaroさんの「結果のリンクを貼る」というのは、アカウント取得が前提です。
  • id:Mook
    最初の回答は単なるバリエーションなので回答不要です。

    よく利用方法を見ていないのですが、アカウントがないと保存できないのでしょうか。
    だとしたら、回答欄のリンクはリンク切れになってしまうのかな?
  • id:practicalscheme
    >yossiy7さん
    確かに "Save this paste" ってリンクがありますね。
    でも私がアカウント無しで書いたコードへのリンクは4日経った今でも有効です。
    もしかして、"Save this paste" は自分のアカウントに紐つけるってことなんじゃないでしょうか。
    saveしなければanonymousでの投稿になると。
  • id:Mook
    先のコメントが間違っていました。

    誤:回答不要
    正:開封不要

    失礼しました。
  • id:garyo
    そろそろ質問が終了してしまうので回答を開きます。
  • id:garyo
    私が昔作ったのは1番の回答者の方と同じような方法でした。
    http://ruby.g.hatena.ne.jp/garyo/20090602/p1
  • id:Chiether
    PHPです。 ほぼ反則なのでコチラへ。 http://codepad.org/CRvY9VHL
    しかしPHPでは、これが正解ですし。 PHPのコンパイラは、正しく認識して、変換し処理しています。
    その証拠に、「No errors or program output.」とは報告されません。(perlやluaだとそうなる)
  • id:practicalscheme
    オーソドックスなquineが意外に少なかったですね

    (オーソドックスなquine:

    次の文をまずプログラムとして、次にデータとして出力せよ。
    「次の文をまずプログラムとして、次にデータとして出力せよ。」

    )

    Lispの循環記法を使うことで、うまくすれば最短かなと思ってたのですが、ChietherさんのPHPに負けました…
  • id:sheile
    ありゃ、rubyで書いてみたけど出遅れたか。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません