自分自身を表示する
Posted feedbacks - Nested
Flatten Hidden久しぶりやってみました。
1 | method(call message previous print) call
|
関数オブジェクト.toString でソースが返ってくるので…
1 2 3 | (function () {
alert("(" + arguments.callee + ")()");
})()
|
エラーで。
1 2 3 | self.rb:1: syntax error, unexpected tINTEGER, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
self.rb:1: syntax error, unexpected tINTEGER, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
^
|
いわゆるクワインですね(Wikipediaにも解説があります)。
see: codepadの遊び方
1 2 | #include<stdio.h>
int main(){char c[]="\\\"#include<stdio.h>%cint main(){char c[]=%c%c%c%.109s%cn%c;printf(c+2,c[109],c[1],*c,*c,c,*c,c[1]);return 0;}\n";printf(c+2,c[109],c[1],*c,*c,c,*c,c[1]);return 0;}
|
Squeak Smalltalk で。
ブロックコンテキスト([])からメソッドをたぐって(method)そのデコンパイルコード文字列(decompileString)からデフォルトのメソッド名(#DoIt)などを削除(allButFirst: 8)して値を返しています。
1 | [] method decompileString allButFirst: 8
|
よくあるコード
1 | main=putStr$q++show q;q="main=putStr$q++show q;q="
|
ラベル付けて自分自身を write に渡します。anarchy golf に投稿したものと同じです。
REPL で実行すると戻り値の表示の際に無限ループするかもしれません。
1 | #1=(WRITE '#1# :CIRCLE T)
|
とりあえず、一番単純なパターンで。
1 | class Sample232{public static void main(String[]a){String s="class Sample232{public static void main(String[]a){String s=%c%s%c;System.out.printf(s,34,s,34);}}";System.out.printf(s,34,s,34);}}
|
1 | (f=^(){ ["(f=", f, ")()"].map(print) })()
|
ごめんなさい
1 2 | $ sh self.sh
cat $0
|
SRFI 38 を使って。
1 | #0=(write/ss '#0#)
|
1 2 3 4 5 6 7 8 9 10 11 12 | f=:0 :0
wd'f=:0 :0'
wd}:f
wd')'
wd}:f
exit''
)
wd'f=:0 :0'
wd}:f
wd')'
wd}:f
exit''
|
GStringで多少Groovyらしくしてみました。
1 | s=';print "s=${39 as char}$s${39 as char}$s"';print "s=${39 as char}$s${39 as char}$s"
|
2番目の条件に該当していないと思いたい。
UBASICで確認。
1 | 10 list
|
これがマシンを起動してから初めて実行するプログラムならいいですが、 場合によっては自分自身以外のコードも表示されてしまいませんかね?
(BASICのステートメントも忘れかけておりますけど)こういうのではいかがでしょう?
1 | 0 DELETE 1- : LIST
|
行番号は0から始まって良いんでしたっけ?私はN88BASIC使いでしたが、0で始めたことは無かったです(大抵100から)
いま手元にあるUBASICだとDELETEも行番号0もダメみたいです。機種やバージョンによって言語仕様がバラバラなのもBASICの特徴。
#8545を投稿したものです。 動作確認をとらずに思いつきで書いてしまいましたが、N-BASIC, MSX-BASICではIllegal Function Callになりました(N88だとSyntax Error)。 私はF-BASIC V3.0で育ったのですが、FM-7は実家に帰らないと確認できません^^; ちなみにF-BASICのリファレンスはなぜか手元にあり、それによると文法上は問題ないように見えますが、確認できないことには。 ちなみにちなみに、行番号0は上述のBAISICすべてで有効でした。 # せっかくどなたか+を付けてくださったようですが、-を付けときます^^;
あ、あとDELETEコマンドもちゃんと存在しました。 > N, M
# アカウント持ってないと評価はできないのかな。すいません、昨日今日立ち寄ったばかりなもので…
ほんの少しだけGroovyらしくしてみました。
see: Grな日々
1 | s=';print "s=${39 as char}$s${39 as char}$s"';print "s=${39 as char}$s${39 as char}$s"
|
1 | (let ((s "(let ((s ~s)) (format (current-output-port) s s))\n")) (format (current-output-port) s s))
|
そういえば、REPL ではこんなのも Quine になります
1 | (PRINC -)
|
初めて書いた。こういう風に書くのね。
1 2 3 4 5 | <?php
$s='<?php
$s=%s%s%s;
printf($s,chr(39),$s,chr(39));';
printf($s,chr(39),$s,chr(39));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
std::string replace(std::string s)
{
std::replace(s.begin(), s.end(), static_cast<char>(std::toupper('n')), '\n');
std::replace(s.begin(), s.end(), static_cast<char>(std::toupper('t')), '\t');
std::replace(s.begin(), s.end(), static_cast<char>(std::toupper('q')), '"');
std::replace(s.begin(), s.end(), static_cast<char>(std::toupper('b')), '\\');
return s;
}
void print(std::string const& s)
{
std::cout << "\t\t\"" << s << "\",\n";
}
void print_r(std::string const& s)
{
std::cout << replace(s);
}
int main()
{
std::string f[] =
{
"#include <iostream>N#include <string>N#include <algorithm>N#include <cctype>N",
"std::string replace(std::string s)N{N",
"Tstd::replace(s.begin(), s.end(), static_cast<char>(std::toupper('n')), 'Bn');N",
"Tstd::replace(s.begin(), s.end(), static_cast<char>(std::toupper('t')), 'Bt');N",
"Tstd::replace(s.begin(), s.end(), static_cast<char>(std::toupper('q')), 'Q');N",
"Tstd::replace(s.begin(), s.end(), static_cast<char>(std::toupper('b')), 'BB');N",
"Treturn s;N}N",
"void print(std::string const& s)N{N",
"Tstd::cout << QBtBtBQQ << s << QBQ,BnQ;N}N",
"void print_r(std::string const& s)N{N",
"Tstd::cout << replace(s);N}N",
"int main()N{NTstd::string f[] =NT{N",
};
std::for_each(f, f + sizeof f / sizeof f[0], print_r);
std::for_each(f, f + sizeof f / sizeof f[0], print);
std::string m = "T};NTstd::for_each(f, f + sizeof f / sizeof f[0], print_r);NTstd::for_each(f, f + sizeof f / sizeof f[0], print);NT";
std::string b = "Q;NTstd::cout << replace(m) << Qstd::string m = BQQ << m << QBQ;BnBtstd::string b = BQQ << b << replace(b) << std::endl;N}";
std::cout << replace(m) << "std::string m = \"" << m << "\";\n\tstd::string b = \"" << b << replace(b) << std::endl;
}
|
1 | Q
|
perlがまだの様なので。
1 2 3 4 5 6 | #! /usr/bin/perl
my $s = '#! /usr/bin/perl%c%cmy $s = %c%s%c;%cprintf $s, 0x0a, 0x0a, 0x27, $s, 0x27, 0x0a, 0x0a, 0x0a, 0x0a;%c%c1;%c';
printf $s, 0x0a, 0x0a, 0x27, $s, 0x27, 0x0a, 0x0a, 0x0a, 0x0a;
1;
|
他の多くの投稿と同じやり方で。
1 2 3 4 | #! /usr/bin/ruby
s = "#! /usr/bin/ruby%c%cs = %c%s%c%cprintf s, 0x0a, 0x0a, 0x22, s, 0x22, 0x0a, 0x0a%c"
printf s, 0x0a, 0x0a, 0x22, s, 0x22, 0x0a, 0x0a
|
コード自身を読み込むコードに該当するかも知れませんが...。
1 2 3 4 5 6 7 8 | #! /usr/bin/ruby
if defined? SCRIPT_LINES__
SCRIPT_LINES__.values.shift.each { |l| print l }
else
SCRIPT_LINES__ = {}
require __FILE__
end
|
Scalaがまだの様なので。
1 2 3 4 5 6 | object PrintSelf {
def main(args:Array[String]):Unit = {
val f:String = "object PrintSelf {%c%cdef main(args:Array[String]):Unit = {%c%c%cval%cf:String = %c%s%c%c%c%cprintf(f, 0x0a, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x22, f, 0x22, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x0a, 0x0a)%c%c}%c}%c"
printf(f, 0x0a, 0x09, 0x0a, 0x09, 0x09, 0x09, 0x22, f, 0x22, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x0a, 0x0a)
}
}
|
1 | $s="$s=%c%s%c;cout<<format($s,34,$s,34);";cout<<format($s,34,$s,34);
|
最後の「val it : unit = ()」を削除すると、Visual Studio 上で実行した場合に要件を満たすコードとなります。
1 | let s="let s=%O%s%O in printf (new PrintfFormat<char->string->char->unit,_,_,_>(s)) (char 34) s (char 34);;//" in printf (new PrintfFormat<char->string->char->unit,_,_,_>(s)) (char 34) s (char 34);;//val it : unit = ()
|
大昔にBASICで書いた記憶があります。
確かこんな感じをDATA文でやっていたような・・・
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #! /usr/bin/ruby
s=""
DATA.each{|d|
s = s + d
}
puts s
puts "__END__"
puts s
__END__
#! /usr/bin/ruby
s=""
DATA.each{|d|
s = s + d
}
puts s
puts "__END__"
puts s
|
1 2 3 4 5 6 7 8 9 10 11 12 13 | using System;
class Quine
{
static void Main()
{
var s = "using System;{2}class Quine{2}{{{2}{4}static void Main(){2}{4}{{";
var t = "{2}{4}{4}var s = {0}{1}{0};{2}{4}{4}var t = {0}{3}{0};{2}{4}{4}";
var u = "var u = {0}{5}{0};{2}{4}{4}var v = {0}{6}{0};{2}{4}{4}var w = {0}";
var v = "{7}{0};{2}{4}{4}Console.Write(s + t + u + v + w, '{0}', s, ";
var w = "Environment.NewLine, t, {0} {0}, u, v, w);{2}{4}}}{2}}}{2}";
Console.Write(s + t + u + v + w, '"', s, Environment.NewLine, t, " ", u, v, w);
}
}
|
SQL Server 2008 で確認しました。 何の面白みもないです・・・
1 | WITH Input(s) AS (SELECT 'WITH Input(s) AS (SELECT #_#) SELECT REPLACE(REPLACE(s, CHAR(35), CHAR(39)), CHAR(95), s) FROM Input;') SELECT REPLACE(REPLACE(s, CHAR(35), CHAR(39)), CHAR(95), s) FROM Input;
|
こうかな
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import std.stdio;
char c = 34;
auto s ="import std.stdio;
char c = 34;
auto s =%s%s%s;
void main() {
writef(s, c, s, c);
}";
void main() {
writef(s, c, s, c);
}
|





greentea #8396() [ Python ] Rating1/1=1.00
いわゆるself-printing programです。 今まで出てなかったっぽいので投稿してみました。 実行すると、そのソースコードの内容をそっくりそのまま表示するコードを書いてください。 ただし、 ・空白のみのコードは認めない ・コードそのものを読み込むコードは書いてはいけない -------->print open('selfprinting.py').read() のようなコード禁止 ・コードを複数のファイルに分けたときは、作成あるいは変更したファイルの内容全てを表示すること -------->foo.pyにprint 'import foo'、main.pyにimport fooのようなコード禁止 ・標準入力や引数、あらかじめあるファイルを都合よく想定するの禁止 -------->print argv[1]として引数に'print argv[1]'を指定ってのはなし ・こういったことをしないで真面目に解いてもらうことを目的としているが、目的通りにいかないことは承知しているし、ある意味、楽しみにしているRating1/1=1.00-0+
[ reply ]