ランダムクイン


15

自分自身をランダムに生成できるプログラムを作成します。

ソースコードで使用されるトークンに基づいてこれを行う必要があります。プログラムのソースコードが50個の一意のトークンで構成され、60個のトークンの長さがある場合、プログラムは各トークンが50個の一意のトークンからランダムに選択される60個のトークンを出力する必要があります。

たとえば、このプログラムは50 ^ 60分の1の確率で自分自身を再現します。

トークンとは何ですか?それは言語に依存します。たとえば、識別子(foo_bar)、キーワード(while)、および数字(42)は、ほとんどの言語でトークンとしてカウントされます。空白はほとんどの言語でカウントされません。

追加のルール:

  • 出力には、プログラムのソースコードにあるトークンのみが含まれ、適切な区切り文字で区切られます
  • 出力は、トークンでカウントされたプログラムのソースコードと同じ長さである必要があります
  • 使用できるプログラミング言語は1つだけです
  • ソースコードには少なくとも3つの一意のトークンが必要です
  • ソースコードからコメントを除外する
  • プログラムは、自分自身を再現する機会がU ^ Lに1つしかないはずです。

スコアリング:自分自身を再現する最良のチャンスがあるプログラムが勝ちます。


@MathieuRodic:あなたは、プログラムが繰り返しなしでトークンを描くと仮定しています。
user2357112は

@MathieuRodic:言い換えさせてください。ソースで使用されるUトークンのセットからLトークンを繰り返し描画するのではなく、プログラムがトークンのマルチセットをランダムにスクランブルすると仮定します。
user2357112は

@ user2357112:なるほど。私の間違いは、この問題を交換せずに引き分けと見なすことでした。
マチューロディック14年

1
ルール1と5は矛盾しているように見えます。
ランチャー14年

4
組み込みのランダム関数がTRNGであると仮定できますか?典型的な実装では、すべての出力を生成するにはシードが小さすぎるため、実際にそれ自体を再生成できない場合があります。
CodesInChaos 14年

回答:


11

Python 2、3 ^ -3 = 0.037

exec乱用は、トークン数を減らすために非常に便利です。ソースファイルを読み取らないように更新されました!

exec '' """
s = '''{a}
s = {b}
s = s.format(a='"'*3, b="'"*3+s+"'"*3)
import random
tokens = ['exec', "''", s]
print random.choice(tokens), random.choice(tokens), random.choice(tokens),
{a}'''
s = s.format(a='"'*3, b="'"*3+s+"'"*3)
import random
tokens = ['exec', "''", s]
print random.choice(tokens), random.choice(tokens), random.choice(tokens),
"""

と巨大な三重引用符で囲まれた文字列の''間の余分なものはexec、トークンカウントを必要最小限3にパディングすることです。暗黙の文字列リテラル連結により、2番目の文字列にマージされます。

オリジナルのソースファイルを開くバージョン:

exec '''
# String literals are one token!
import random
import tokenize

with open(__file__) as f:
    tokens = [x[1] for x in tokenize.generate_tokens(f.readline)][:-1]

''' '''
# Splitting the string into two strings pads the token count to the minimum of 3.

print random.choice(tokens), random.choice(tokens), random.choice(tokens),
'''

厳密に言えば、Pythonの文法はソースファイルの最後にENDMARKERトークンを配置し、ENDMARKERがランダムにばらまかれたソースファイルを生成することはできません。存在しないふりをします。


@Cruncherそれは確率です。3 ^ -3 ==
オースティンヘンリー14年

2
ルールの素晴らしいハックに対して+1。J:で実装された同じアイデア".]';(?3 3 3){]`".;~({:,],{:,],6#{:)'';(?3 3 3){]`".;~({:,],{:,],6#{:)'''''''
algorithmshark 14年

5

Javascript、102トークン、33ユニーク、7.73×10 -154

注意してください、これは本当の馬です。ファイルを読み取ったり、使用しevalたりしませんFunction.toString

meta = "meta = ; out = '' ; tokens = meta . split ( '\\u0020' ) ; tokens . push ( '\"' + meta + '\"' ) ; length = tokens . length ; tmp = length ; unique = { } ; while ( tmp -- ) unique [ tokens [ tmp ] ] = unique ; unique = Object . keys ( unique ) ; tmp = unique . length ; while ( length -- ) out += tokens [ ~~ ( Math . random ( ) * tmp ) ] + '\\u0020' ; console . log ( out )"; 
out = '';
tokens = meta.split('\u0020');
tokens.push('"' + meta + '"');
//console.log(tokens);
length = tokens.length;
tmp = length;
unique = { };
while(tmp--) unique[tokens[tmp]] = unique;
unique = Object.keys(unique);
//console.log(unique);
tmp = unique.length;
while(length--)
    out += unique[~~(Math.random() * tmp)] + '\u0020';
console.log(out)

4

Python:P(1回の試行でプログラムを生成)= 3.0317 * 10 ^ -123

34個の一意のトークン、合計80個のトークン。各行の終わりにスペースがあることに注意してください。

import tokenize , random 
tokens = [ x [ 1 ] for x in tokenize . generate_tokens ( open ( __file__ , 'r' ) . readline ) ] [ : -1 ] 
s = '' 
for x in tokens : s += random . choice ( list ( set ( tokens ) ) ) ; s += [ ' ' , '' ] [ s [ -1 ] == '\n' ] 
print s 

サンプル出力:

' ' random len set 'r' , for ( list , import ] ] tokens : random [ for '\n' import readline readline 'r' tokens [ len 'r' import '' choice '' '' for in ( readline ( = open readline , list 1 list s += for s 1 , '' : 1 += list len - __file__ ; open __file__ print . - ] 'r' for import [ print . , 

; . [ [ print print __file__ generate_tokens ] ; open ] , readline 

最後のトークンを破棄し、__file__以前は無知だった使用を思い出させてくれたuser2357112による他のPythonソリューションに感謝します。


3

J-1 in 11 17 = 1.978 x 10 -18

;(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)'''

Jには、これらの種類のジョブを実行するための便利な小さなツールがたくさんあります。

  • まず、スペースで区切られた数字の文字列は1つのトークンです。これは、これらの数値の1次元配列を意味します。これがJのレクサーの仕組みです。ちなみに、11誰かが好奇心if盛なら、それは17 秒です。

  • (,,,{:,{:)'QUINE'''は、Jの一般的なクイントリックであり、できるだけ少ないトークンを使用するように作られています:Tailを{:意味するため、文字列を自分自身に追加し、最後の文字のコピーをその末尾に追加します 最後の文字は一重引用符であるため(JはPascalスタイルの文字列を使用)、結果はになります。QUINE'QUINE'''

  • ;:はトークナイザーであり、入力文字列をJコードであるかのように分割し、ボックスのリストを返します。この結果の長さは17です。

  • ~.この配列のすべての一意の要素を取ります。この結果の長さは11です。

  • ?Rollと呼ばれます。引数内の整数ごとに、ゼロ以上でその数より小さい正の乱数を選択します。したがって、Jは0から10までの17個の数値を生成します。

  • { ランダムインデックスを使用して、unique-tokens-in-boxesのリストからアイテムを選択します。

  • ; これらすべてのボックスを開き、結果を一緒に実行します。

次に例を示します。インデントされた行は入力プロンプトであり、左側に並ぶ行はインタープリターの出力です。

   ;(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)'''
~.~.(?;;:11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)'''(){11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){(;:;
   ;(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)'''
{';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)''',?{:;:{:';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)'''11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11{:{;(;:{:,~.

2

追記

これは楽しいものでした

/cvx /cvx cvx /exec /exec cvx /dup /rand /mod /get /== /array /astore /realtime
/srand /repeat 6 17 54 17 /array cvx exec /astore cvx exec 54 /dup cvx /rand
cvx 17 /mod cvx /get cvx /== cvx 6 /array cvx exec /astore cvx exec cvx /realtime
cvx exec /srand cvx exec /repeat cvx exec

3.6e-67の確率で約1の合計17個の一意のトークンと54個のトークンがあります。


2

空白、3 ^ -205 3 ^ -189 3 ^ -181 3 ^ = 10 ^ -63

これは、ランダムな文字をシードすると、3 ^ 132分の1の確率で自身を複製するホワイトスペースプログラムです(3つの異なるトークン、132回繰り返されます)。実行時には、少なくとも132個のランダムな文字をシードする必要があります(ホワイトスペースには、シードする組み込みのランダム関数や日付関数はありません)some_whitespace_interpreter my_quine.ws <some_random_source >quine_output.ws。プログラムをこれ以上ゴルフできるようになればスコアは改善されますが、これは私の最初の「本当の」ホワイトスペースプログラムです。そのため、わずかな量のゴルフだけを残します。

プレーンホワイトスペースコード、または実行を確認:(試してみるには、「編集」をクリックし、<pre>タグ内の内容をコピーします。UnixスタイルのEOLでは132文字にする必要があります)

    

























whatコマンドで注釈されたコードは何ですか(技術的にはクインではありません、コメントを再現しないため):

スタックpush_number + 0 end
スタックpush_number + 1 0 0 1 end
ヒープストアスタックpush_number + 1 end
スタックpush_number + 1 0 0 0 0 0 end
ヒープストアスタックpush_number + 1 0 end
スタックpush_number + 1 0 1 0 end
ヒープストアスタックpush_number + 1 0 0 0 0 0 1 1 end
フロー
make_label loop_begin  
スタックpush_number + 1 1終了
IO  
文字スタックの読み取りpush_number + 1 1 end
ヒープ取得スタックpush_number + 1 1 end
算術モジュロヒープ取得IO  
文字スタックのプッシュpush_number + 1終了
算術減算スタックの複製
 フロー
jump_if_zero end_prog
フロー
jump_to 
loop_begin  
フロー
make_label end_prog
フロー
end_program

シードがたまたまこれと同じ場合(文字はmod 3でトークンに変換される)、これは成功します:

CCCCACCCBCCBABBCCCCBACCCBCCCCCABBCCCCBCACCCBCBCABBCCCCBCCCCCBBAACCBACCCBBABABCCCCBBABBBCCCBBABCBBBBBBACCCCCBABCCBCACABBAACABAACCAAAA

これは非常に単純なプログラムで、このRubyプログラムとほぼ同等です。

i = 131
while true
    print '\t \n'[STDIN.getc.ord % 3]
    i = i - 1
    break if i < 0
end

1

Perl、27トークン、P = 1.4779 x 10 -34

@ARGV=$0;print$W[rand@W]for@W=split/(\W)/,readline

最終編集:トークンを保存する@ARGV=$0代わりに使用open*ARGV,$0します。

  • 15個の一意のトークン
  • 4つのトークンは(2回現れ=/@$
  • 1つのトークンが4回表示されます(W

だから、それは確率(pow(2,2 * 4)* pow(4,4))/ pow(27,27)、約1.48E-34になると思います。

ソースコードがというファイルにある場合、ARGVP =〜2.193 x 10 -31でこの26トークンソリューションを使用できます。

@ARGV=ARGV;print$ARGV[rand@ARGV]for@ARGV=split/(\W)/,readline

実際にはP = (4 * 2! + 4!) / 27!、これは約1.7632684538487448 x 10 ^ -26
Mathieu Rodic 14年

0

Perl 6133 = 0.037037 ...

(これはコードゴルフではないことを知っていますが...)

q[say |roll <<~~"q[$_]".EVAL>>: 3]~~.EVAL

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

Pythonの回答とほぼ同じです。最初のトークンは評価される文字列リテラルです。トークンは

q[say |roll <<~~"q[$_]".EVAL>>: 3]   String literal
~~                                   Smartmatch operator
.EVAL                                Function call

説明:

q[say |roll <<~~"q[$_]".EVAL>>: 3]         # Push as string literal
                                  ~~       # Smartmatch by setting $_ to the string literal
                                    .EVAL  # Eval the string
            <<~~"q[$_]".EVAL>>             # From the list of tokens
       roll                   : 3          # Pick 3 times with replacement
  say |                                    # Join and print
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.