最短の自己識別プログラム(キインバリアント)を書く


57

入力がプログラムのソースコードに一致する場合は「true」の出力を生成し、入力がプログラムのソースコードに一致しない場合は「false」の出力を生成するプログラムを作成します。

この問題は、プログラムがプロセス内で独自のソースコードを何らかの方法で計算できる必要があるため、クインに関連していると説明できます。

これはコードゴルフです。標準ルールが適用されます。プログラムは、独自のソースコードのファイルなどの特別なファイルにアクセスしてはなりません。

編集:そのように選択した場合、true / falseはTrue / Falseまたは1/0に置き換えることができます。

プログラムのソースコードがの場合、bhiofvewoibh46948732));:/)4プログラムで実行する必要があることは次のとおりです。

入力(標準入力)

bhiofvewoibh46948732));:/)4

出力(標準出力)

true

入力

(Anything other than your source code)

出力

false

7
あるtrue/ false(出力が強く要求、またはバリエーションであるTrue/ False1/ 0も許容されますか)?
クリスティアンルパスク

プログラムが真/偽よりも少し多く出力する場合(明確であり続け、真/偽で終わる場合)、それは問題ですか?
デニーズセグレ


5
だから、ナルシストのプログラムですか?
PyRulez

回答:


33

JavaScript:26

function f(s){return s==f}

JavaScriptファイルが本当に「プログラム」として適格であるかどうかはわかりません。



これは矢印関数を使用して短縮できますf=s=>s=='f='+f
ジョナサン

2
@ジョナサンはい。しかし、2013年にはできませんでした。
DenysSéguret18年

19

JavaScript ES6、9文字

これは、JSで行う唯一の(ゴルフ)方法です。ES6では、文字数が非常に少なくなります

これを最新のFirefoxのWebコンソールで実行します。

f=x=>f==x

使用例:

f("check") // returns false
f("x=>f==x") // returns true

1
@phinotpi-私のエントリはまだ回答として選ばれる資格がありますか?
オプティマイザー

6
しかし、この場合のソースはf=x=>f==xでありx=>f==x、ではない、と主張することができますが、DenysSéguretのバージョンはソース全体を実際にチェックします。
ハンクレコード

@Hankrecords JavaScriptにそれを決定させます。 f=x=>f==x function f() f.toSource() "x=>f==x"(基本的にコンソールでコードを評価f.toSource()し、そのメソッドをサポートするブラウザーで評価します
オプティマイザー

匿名関数は許可されていません(コードをに短縮x=>f==x)編集:nevermind、fは関数の内部で参照されます
MilkyWay90

9

Haskell、72文字

main=interact$show.(==s++show s);s="main=interact$show.(==s++show s);s="

注:スクリプトの最後に行末文字はありません。

$ runhaskell Self.hs < Self.hs
True

8

GolfScript、11文字

{`".~"+=}.~

がない場合=、このコードは独自のソースコードを文字列として生成するクインになります。=それはその入力と出力にこの文字列を比較します1それらが一致する場合と0そうでない場合。比較は正確であることに注意してください。特に、入力の最後にある改行が原因で失敗します。

説明:

  • { } GolfScriptのコードブロックリテラルです。
  • .このコードブロックを複製し~、2番目のコピーを実行します(最初のスタックをスタックに残します)。
  • `コードブロックを文字列化し、".~"+を追加.~します。
  • 最後に=、結果の文字列を入力(プログラムの開始前にGolfScriptインタープリターによって文字列としてスタックにプッシュされる)と比較し、1一致する場合と一致0しない場合に戻ります。

7

Perl、Infinity 41 38文字

$_=q(print<>eq"\$_=q($_);eval"|0);eval

更新:プログラムは改行で終了しなくなりました。つまり、複数行のファイルで正しく動作します。Enterを押すことなく、STDINから入力を入力する必要があります。Windowsでは、ファイルから読み取ることによってのみこれを行うことができました。

元のソリューション:

print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(print<>==q(...

1
よくできました!。。。
暴徒

コードで始まるファイル、例えばのために失敗した(cat id.pl; echo foo)|perl id.pl
ジェフ・リーディ

@GeoffReedy、ありがとう。プログラムは以前は複数行の入力を処理しませんでした。現在修正されています。

くそー、このコードはボウリングですか?
マシュー

7

> <>、68バイト

魚は魚の糞を食べるのが大好きです。今、彼らは彼らを彼らの友人と区別できることを知っています。

00v      0+1~$^?)0~\;n0\
  >:@@:@gi:0(?\:a=?/=?!/$1+
  0n;n*=f$=2~~/

オンラインで試すことができます


1
これ1により、コードのプレフィックスも出力されます
ジョーキング

@JoKingそれはスクリプトの単なる接頭辞よりも最悪で、切り捨てられた行も受け入れました!私はそれを修正しましたが、それが望んでいたほど一般的ではないことに失望しています。スクリプトの最後に到達したセルをチェックして、コード全体が一致したことを確認する必要がありました。確かに改善できますが、気にするかどうかはわかりません。
アーロン

6

Python 2、55

a='a=%r;print a%%a==raw_input()';print a%a==raw_input()

テスト済み:

a='a=%r;print a%%a==raw_input()';print a%a==raw_input() -> True

(anything else) -> False


3
に等しい最初の行で始まるファイルで失敗しますa='a=%r;print a%%a==raw_input()';print a%a==raw_input()
ブースバイ

確かに、複数行入力はサポートされていません。
flornquake

些細な修正はに置き換えるraw_input()こと__import__('sys').stdin.read()です。
feersum

チャレンジの言葉遣いに戸惑っています(私は英語の文法が苦手だからです)。これは許可されていますか?print raw_input()==open(__file__).read()?わずか40バイトで、raw_input()アプローチを使用しますが、コードを読み取ります。
サイモン

1
@Simon許可されていません。これは、このような課題の標準的な抜け穴の1つです。そして、はい、これはそれが何を意味するのかであるYour program must not access any special files, such as the file of its own source code.
PunPun1000

6

JavaScriptのES6、16の 14バイト

$=_=>_==`$=`+$

Neilのおかげでマイナス2バイト。

プロンプト経由で入力する必要がある場合は31バイト。

$=_=>prompt()==`$=${$};$()`;$()

アラート経由で出力する必要がある場合は38バイト。

$=_=>alert(prompt()==`$=${$};$()`);$()

オプティマイザーの答えはソースコード全体を受け入れないため、これは適切な方法です。


1
いいですね、ただ書くだけ'$='+$です。
ニール

ああ、本当。@ニール
コナーオブライエン

1
;$()関数呼び出しはクインの一部であるため、エンディングが必要になると確信しています。これはまたprompt、入力のアカウントに切り替える必要があることも意味します。
ママファンロール

1
それは問題ではありません。関数呼び出しはそれがクインの一部であるために必要です。ユーザーが関数として呼び出すことを許可すると、クインが台無しになります。
ママファンロール

1
試してください$=_=>prompt()==`$=${$};$()`;$()
ママファンロール

5

Node.js:54

function f(){console.log(f+'f()'==process.argv[2])}f()

それをファイルに保存してf.js(正確な名前は重要ではありません)テストします

node f.js "test"

(これはfalseを出力します)または

node f.js "$(< f.js)"

(これはtrueを出力します)

また、evalに基づいて異なるバージョンを作成しました。

eval(f="console.log('eval(f='+JSON.stringify(f)+')'==process.argv[2])")

現在は72文字になっています。時間があれば、それを短くしようとします。


1
@ dan1111なぜ?ファイルにはアクセスしません。私は、node.jsに慣れていない人にプログラムを起動する方法を指していました。ファイルを読み取りません。
デニスセグレ

1
JavaScriptソリューションはすべて、JSで独自のソースコードにアクセスできるという事実を利用しています。それは技術的には「独自のソースコードのファイルにアクセスする」ことではないかもしれませんが、まったく同じことを達成します。質問はこれを特に禁止していないので、あなたの答えは合法だと思います。

さて、プログラムの一部である関数のソース(正確には本体のみ)にアクセスします。それはDでmixin()を使用するようなものです。しかし、私からの1つを含む他の2つのJSの回答は、実際には「プログラム」としての資格があるとは思いません。
デニーズセグレ

実際Dにミックスイン@dystroyは、複数のソースを読むことよりもevalの使用のようなものである
フリークラチェット

@ratchetfreakはい、そうです。しかし、あなたのプログラムは一種の列挙値のtoStringを使用していると思いますよね?そして、eval / mixinを使用するコードは、関数のソースを使用するのとほぼ同じトリックです。
デニーズセグレ

5

Smalltalk(Pharo 2.0方言)

この41文字のメソッドをStringに実装します(code-golfのformattingいフォーマット):

isItMe^self=thisContext method sourceCode

次に、ワークスペースでこれを評価します(printItは従来のSmalltalkの方法です)
入力はstdinから読み取られません。メッセージを送信する文字列です(Smalltalkで他にプログラムがあるとしたらどうでしょうか)。

'isItMe^self=thisContext method sourceCode' isItMe.

しかし、我々はごまかしています。sourceCodeはいくつかのソースファイルを読み取ります...
以下は51文字のバリアントです。

isItMe
    ^ self = thisContext method decompileString

そしてテスト:

'isItMe
    ^ self = thisContext method decompileString' isItMe

ワークスペース内の文字列が有効な入力と見なされない場合、116文字でダイアログボックスを使用する方法を見てみましょう。次の
文を評価してください。

(UIManager default request: 'type me') = (thisContext method decompileString withSeparatorsCompacted allButFirst: 7)

逆コンパイル形式にはCRとTABが含まれているため、withSeparatorsCompactedを変更します。
次に、最初の7文字をスキップします 'doIt ^'

最後に、stdinを使用した105文字のバリアントは、コマンドラインからこの文を解釈するだけで、より主流になります。

Pharo -headless Pharo-2.0.image eval "FileStream stdin nextLine = (thisContext method decompileString withSeparatorsCompacted allButFirst: 7)"

4

フレックス-312文字

Q \"
N \n
S " "
B \\
P "Q{S}{B}{Q}{N}N{S}{B}n{N}S{S}{Q}{S}{Q}{N}B{S}{B}{B}{N}P{S}{Q}{P}{Q}{N}M{S}{Q}{M}{Q}{N}%%{N}{P}{N}{M}{N} putchar('1');"
M "(.|{N})* putchar('0');"
%%
Q{S}{B}{Q}{N}N{S}{B}n{N}S{S}{Q}{S}{Q}{N}B{S}{B}{B}{N}P{S}{Q}{P}{Q}{N}M{S}{Q}{M}{Q}{N}%%{N}{P}{N}{M}{N} putchar('1');
(.|{N})* putchar('0');

おそらく短くすることができますが、複数行の入力(ソースコードが複数行であるために必要です)およびサブストリングとしてプログラムを含む入力でも機能します。これまでの回答の多くは、これらの一方または両方で失敗したようです。

コンパイルコマンド: flex id.l && gcc -lfl lex.yy.c


3

D(133文字)

enum c=q{import std.stdio;import std.algorithm;void main(){auto i=readln();writeln(equal("auto c=q{"~c~"};mixin(c);",i));}};mixin(c);

3

JavaScript(V8)、35

function i(){alert(prompt()==i+[])}

呼び出してi()、入力を促します


+[]JSはそれを自動型キャストされますよう、オプションでなければなりません
Downgoat


3

Python 2、47バイト

_='_=%r;print _%%_==input()';print _%_==input()

チェックが追加された単純なクイン。


これは機能しません。printある機能は、あなたがする必要があると思いPythonの3であるprint(_%%_==input())';print(_%_==input())か、Pythonの2に変更し
MEGO

3

CJam、12バイト

{s"_~"+q=}_~

オンラインでお試しください!

説明

これは、標準のCJam quineフレームワークを使用します。

{s"_~"+q=}    e# Push this block (function literal).
          _~  e# Copy and run it.

ブロックの機能:

 s            e# Stringify the top element (this block itself).
  "_~"+       e# Append "_~". Now the source code is on the stack.
       q      e# Read the input.
        =     e# Check if it equals the source code.

これはまさに私が持っていた解決策です。
エソランジングフルーツ


2

Perl、52文字

$_='$/=$\;$_="\$_=\47$_\47;eval";print<>eq$_|0';eval

2

Python、187バイト

import sys;code="import sys;code=!X!;print(sys.stdin.read()==code.replace(chr(33),chr(34)).replace(!X!,code,1))";print(sys.stdin.read()==code.replace(chr(33),chr(34)).replace("X",code,1))

最後に改行を追加しないように注意してください。より良いPython-fuを持っている人はそれを短くできるかもしれません。


2
を使用C=chrして、いくつかのバイトをドロップできます。また、変数名を短くしますcode
ザックゲイツ

2
1年以上誰もそれを言っていないので、PPCGへようこそ!
エリックアウトゴルファー

2

、11バイト

=hS+s"=hS+s

オンラインでお試しください!

説明

説明では¨、文字列を区切るために使用しています(読み取り不能なエスケープを回避するため)。

     "=hS+s  -- string literal: ¨=hS+s¨
  S+         -- join itself with
    s        -- | itself "showed": ¨"=hS+s"¨
             -- : ¨=hS+s"=hS+s"¨
 h           -- init: ¨=hS+s"=hS+s¨
=            -- is the input equal?

関数=を削除することで、ソース自体にのみ一致することを確認できます。




2

05AB1E、15 バイト

0"D34çýQ"D34çýQ

追加してデフォルトの 変更します(暗黙的な入力との等価性をチェックします)0"D34çý"D34çýQ

オンラインでお試しください。

説明:

0                # Push 0 to the stack
                 #  STACK: [0]
 "D34çýQ"        # Push the string 'D34çýQ' to the stack
                 #  STACK: [0, 'D34çýIå']
         D       # Duplicate this string
                 #  STACK: [0, 'D34çýIå', 'D34çýIå']
          34ç    # Push '"' to the stack
                 #  STACK: [0, 'D34çýIå', 'D34çýIå', '"']
             ý   # Join the stack by this '"' delimiter
                 #  STACK: ['0"D34çýIå"D34çýIå']
              Q  # Check if it's equal to the (implicit) input
                 # (and output the top of the stack implicitly as result)

@Grimyが提供する15 バイトのクールな代替手段:

187745012D27BJQ

オンラインでお試しください。

説明:

187745012        # Push integer 187745012 
                 #  STACK: [187745012]
         D       # Duplicate it
                 #  STACK: [187745012, 187745012]
          27     # Push integer 27
                 #  STACK: [187745012, 187745012, 27]
            B    # Convert 187745012 to base-27
                 #  STACK: [187745012, "D27BJQ"]
             J   # Join the values on the stack together
                 #  STACK: ["187745012D27BJQ"]
              Q  # Check if it's equal to the (implicit) input
                 # (and output the top of the stack implicitly as result)

3
187745012D27BJQネクタイです。
グリムミー

1

C- 186 176文字

一発ギャグ:

 *a="*a=%c%s%c,b[999],c[999];main(){sprintf(b,a,34,a,34);gets(c);putchar(strcmp(b,c)?'0':'1');}",b[999],c[999];main(){sprintf(b,a,34,a,34);gets(c);putchar(strcmp(b,c)?'0':'1');}

空白あり(これによりプログラムが中断されることに注意してください):

*a="*a=%c%s%c,b[999],c[999];main(){sprintf(b,a,34,a,34);gets(c);putchar(strcmp(b,c)?'0':'1');}",b[999],c[999];
main() {
  sprintf(b,a,34,a,34);
  gets(c);
  putchar(strcmp(b,c)?'0':'1');
}




1

ルーン文字、11バイト

"3X4+kSqi=@

オンラインでお試しください!

TIOが更新され、入力の読み取りに関する問題はなくなりました(末尾の空白は不要になりました)。

説明

>                 Implicit entry
 "                Begin reading as string
  3X4+kSqi=@      Pushed to the stack as a string, loop around
 "                End reading as string
  3X4+            Push 3*10 and 4 to the stack, add them together
      k           Convert to character (")
       S          Swap the top two items on the stack
        q         Concatenate. This leaves only "3X4+kSqi=@ on the stack
         i        Read input
          =       Compare using .Equals, push 1 if equal, else 0
           @      Print and terminate

JoKingのソリューション:

"'<~qi=@|

説明

  <              Entry
 '               Read character (loop around)
"                Push "
         |       Mirror
"                Begin reading string (loop around)
 '<~ri=@|        Push the string '<~qi=@| (loop around)
"                End reading string
 '<~             Push the character < and then discard it
    q            Concatenate, stack contains only "'<~qi=@|
      i          Read input
       =         Compare
        @        Print and terminate


@JoKing非常に賢い。
Draco18s

実際、9バイトr逆方向を回避します
ジョーキング

@JoKing私はおそらく自分で(10バイトのソリューションから)それにたどり着くことができたはずですが、まだcawfeeを持っていません。昨日"は、左側に配置することが本当にできる唯一の場所であるとすでに考えていました。他の場所に配置すると複雑になるためです。(しかし、今はデバッガーで実行して、それが何をしていたかを確認しなければなりませんでした...)
Draco18s

1

R、54バイト

f=function(s)s==paste0("f=function(s)s==", body(f)[3])

オンラインでお試しください!

body関数の本体を取得します(少し分割するので、それ以降body(f)[3]はすべてpaste0です)。興味深いことに、bodyコンマの後にスペースを追加するなど、コードを再フォーマットします。したがって、これはコンマの後にスペースがあるRゴルフの回答のまれなケースです。

これbody(f)は、タイプのオブジェクトであるため機能し、このタイプのメソッドlanguageが存在しas.characterます。一方、fand args(f)はtype closureであり、私が知る限り、文字型に変換することはできません。言語タイプが何であるかを聞かないでください…


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.