Rastgele Quine


15

Rastgele kendini üretebilen bir program yazın.

Bunu , kaynak kodunda kullanılan belirteçlere dayanarak yapmalıdır . Programınızın kaynak kodu 50 benzersiz belirteçten oluşuyorsa ve 60 belirteç uzunluğundaysa, programın her belirteç 50 benzersiz belirteçten birinden rastgele seçildiği 60 belirteç çıkarmalıdır.

Örneğin, bu programın kendini çoğaltma şansı 50 ^ 60.

Jeton nedir? Bu dile bağlıdır. Örneğin, tanımlayıcılar ( foo_bar), anahtar kelimeler ( while) ve sayılar ( 42) çoğu dilde belirteç olarak sayılır. Beyaz alan çoğu dilde sayılmaz.

Ek kurallar:

  • Çıktı, yalnızca programın kaynak kodunda bulunan ve uygun sınırlayıcıyla ayrılmış jetonları içerebilir
  • Çıktı, programın kaynak koduyla aynı uzunlukta olmalı ve belirteçlerle sayılmalıdır
  • Yalnızca bir programlama dili kullanılabilir
  • Kaynak kodda en az 3 benzersiz simge bulunmalıdır
  • Yorumları kaynak koddan hariç tutma
  • Programın yalnızca kendi kendini üretme şansına sahip olması gerekir

Puanlama: Kendini çoğaltma şansı en yüksek olan program kazanır.


@MathieuRodic: Programın tekrar etmeden jeton çektiğini varsayıyorsunuz.
user2357112 Monica

@MathieuRodic: Yeniden ifade edeyim. Programın, kaynağında kullanılan U jetonları kümesinden tekrarlı olarak L jetonlarını çizmek yerine jetonlarının çoklu kümesini rastgele karıştırdığını varsayıyorsunuz.
user2357112 Monica

@ user2357112: Anlıyorum. Benim hatam bu sorunu yerine bir beraberlik olarak düşünmek oldu.
Mathieu Rodic

1
Kural # 1 ve # 5 bana aykırı görünüyor.
Cruncher

4
Yerleşik rastgele işlevlerin TRNG'ler olduğunu varsayabilir misiniz? Tipik uygulamalar, tüm çıktıları üretmek için çok küçük tohumlara sahiptir ve bu nedenle gerçekte kendini yenileyemeyebilir.
CodesInChaos

Yanıtlar:


11

Python 2, 3 ^ -3 = 0.037

execkötüye kullanım, jeton sayısını azaltmak için oldukça kullanışlıdır. Şimdi kaynak dosyayı okumamak için güncellendi!

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),
"""

İlave ''arasında execve dev üçlü tırnaklı dize nedeniyle örtülü dize birbirine bağlanmasına yol ped sadece İkinci dize birleştirilecek alır 3'ün gerekli minimum belirteç sayısıdır.

Orijinal, kaynak dosya açma sürümü:

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),
'''

Açıkça söylemek gerekirse, Python dilbilgisi kaynak dosyanın sonuna bir ENDMARKER jetonu yerleştirir ve ENDMARKER'ların rastgele dağıldığı bir kaynak dosyası üretemeyiz. Biz yokmuş gibi yapıyoruz.


@Cruncher Bu olasılık. 3 ^ -3 ==
Austin Henley

2
Kuralların mükemmel bir şekilde kesilmesi için +1. Aynı düşünce J uygulanan: ".]';(?3 3 3){]`".;~({:,],{:,],6#{:)'';(?3 3 3){]`".;~({:,],{:,],6#{:)'''''''.
algoritmalarhark

5

Javascript, 102 jeton, 33 benzersiz, 7.73 × 10-154

Bu gerçek bir soru. Dosyayı okumuyor veya kullanmıyor evalveyaFunction.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 denemede program oluşturma) = 3.0317 * 10 ^ -123

34 benzersiz belirteç, 80 toplam belirteç. Her satırın sonunda bir boşluk olduğunu unutmayın.

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 

Örnek çıktı:

' ' 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 

User2357112 tarafından daha önce bilmediğim son jetonu ve kullanımı atmamı hatırlattığı için diğer Python çözümü __file__sayesinde.


3

J - 1 11 17 x 10 = 1.978 -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, bu tür işleri yapmak için kullanışlı küçük araçlara sahiptir.

  • Her şeyden önce, boşlukla ayrılmış sayı dizisi bir jetondur . Bu sayıların tek boyutlu dizisi anlamına gelir. J'nin lexeri böyle çalışır. Bu arada, 11eğer biri meraklıysa , bu on yedi .

  • (,,,{:,{:)'QUINE'''J'de, olabildiğince az jeton kullanmak için yapılan yaygın bir tırnak hilesi: Kuyruk{: anlamına gelir , bu nedenle dizeyi kendisine ekler ve ardından son karakterin iki kopyasını sonuna ekler. Son karakter tek bir alıntı olduğundan (J Pascal tarzı dizeler kullanır) sonuç ortaya çıkar .QUINE'QUINE'''

  • ;:bir belirteçtir ve bir giriş dizesini J kodu gibi ayırır ve bir kutu listesi döndürür. Bu sonucun uzunluğu 17'dir.

  • ~.bu dizinin tüm benzersiz öğelerini alır. Bu sonucun uzunluğu 11'dir.

  • ?Roll denir . Bağımsız değişkenindeki her tam sayı için, sıfırdan büyük veya sıfıra eşit, bu sayıdan küçük rastgele bir pozitif sayı seçer. Yani burada J 0'dan 10'a kadar 17 sayı üretecektir.

  • { kutulardaki benzersiz jetonlar listemizdeki öğeleri seçmek için rastgele dizinleri kullanır.

  • ; tüm bu kutuları açar ve sonucu birlikte çalıştırır.

Aşağıda bazı örnekler verilmiştir. Girintili çizgiler giriş komutlarıdır ve sol tarafla aynı hizaya gelen çizgiler tercümanın çıktısıdır.

   ;(?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

dipnot

Bu eğlenceliydi

/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 şansında yaklaşık 1 olmak üzere toplam 17 benzersiz token ve 54 token bulunmaktadır.


2

Boşluk, 3 ^ -205 3 ^ -189 3 ^ -181 3 ^ -132 ~ = 10 ^ -63

Bu, rastgele karakterler ile tohumlandığında, kendini yeniden üretme şansına sahip 1'de 3 ^ 132 şansına sahip olan (3 ayrı jeton, 132 kez tekrarlanan) bir Whitespace programıdır. Çalıştırıldığında en az 132 rasgele karakterle tohumlanmalıdır, (Beyaz boşlukta yerleşik rasgele veya tarih fonksiyonu yoktur) örn some_whitespace_interpreter my_quine.ws <some_random_source >quine_output.ws. Program daha fazla golf yapılabilirse skor daha iyi olurdu, ama bu benim ilk "gerçek" Whitespace programım, bu yüzden sadece az miktarda golf ile bırakacağım.

Düz Boşluk kodu veya çalıştırıldığını görün : (denemek için "düzenle" yi tıklayın, <pre> etiketlerinin içine kopyalayın; Unix stili EOL ile 132 karakter olmalıdır)

    

























Hangi komutun ne olduğuna açıklanan kod (açıklamaları yeniden oluşturmayacağından teknik olarak bir quine değil):

yığın itme_sayısı + 0 son
yığın itme_sayısı + 1 0 0 1 son
öbek deposu yığını push_number + 1 son
yığın push_numarası + 1 0 0 0 0 0 son
öbek deposu yığını push_number + 1 0 son
yığın push_numarası + 1 0 1 0 son
yığın yığını yığın_sayısı + 1 0 0 0 0 0 1 1 son
akış
make_label loop_begin  
yığın itme_sayısı + 1 1 son
IO  
karakter yığınını oku push_number + 1 1 end
yığın yığını almak push_number + 1 1 son
aritmetik modulo yığın almak IO  
print char stack push_number + 1 son
aritmetik çıkarma yığını yinelenen
 akış
jump_if_zero end_prog
akış
atlamak 
loop_begin  
akış
etiket_etiketi
akış
end_program

Tohum eşdeğer olursa (karakterler jetonlara dönüştürülmek üzere mod 3 alınır) başarılı olur:

CCCCACCCBCCBABBCCCCBACCCBCCCCCABBCCCCBCACCCBCBCABBCCCCBCCCCCBBAACCBACCCBBABABCCCCBBABBBCCCBBABCBBBBBBACCCCCBABCCBCACABBAACABAACCAAAA

Oldukça basit bir program, bu Ruby programına kabaca eşdeğer:

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

1

Perl, 27 jeton, p = 1,4779 x 10 -34

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

Son düzenleme: bir jetonu kaydetmek @ARGV=$0yerine kullanın open*ARGV,$0.

  • 15 benzersiz token
  • 4 belirteçleri görünür 2 kez ( =, /, @, $)
  • 1 belirteç 4 kez görünür ( W)

Bu yüzden bu olasılığı (pow (2,2 * 4) * pow (4,4)) / pow (27,27), yaklaşık 1.48E-34 yapar.

Kaynak kodu adlı bir ARGVdosyadaysa, bu 26 belirteç çözümünü P = ~ 2.193 x 10 -31 ile kullanabilirsiniz :

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

Aslında, P = (4 * 2! + 4!) / 27!yaklaşık 1.7632684538487448 x 10 ^ -26
Mathieu Rodic

0

Perl 6 ,1 içinde 33 = 0.037037 ...

(Bunun kod golf olmadığını biliyorum, ama ...)

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

Çevrimiçi deneyin!

İlk token değerlendirilen bir dize değişmezi olan Python cevabı ile hemen hemen aynı. Jetonlar

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

Açıklama:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.