En uzun periyot yineleme


10

Bildiğimiz gibi, bir quine kendi kaynak kodunu veren bir programdır. Ancak, başka bir program çıkaran ve ilk programı yeniden çıkaran bir program yazmak da mümkündür. Örneğin, Python 2 programı

x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3

çalıştırıldığında aşağıdaki metni çıktılar:

print """x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3"""

Bir Python programı olarak çalıştırıldığında, orijinal kod tekrar çıkar. Buna yinelemeli bir quine denir . Orijinal kodu geri almak için iki kez çalıştırmanız gerektiğinden, bunun 2. periyodu olduğunu söylüyoruz . Ancak elbette çok daha yüksek süreler mümkündür.

Zorluğunuz 100 bayt veya daha kısa bir sürede seçtiğiniz dilde olabildiğince uzun bir süre ile yinelenen bir quine yazmaktır . (Yukarıdaki örneğimin, son satırsonu dahil 119 bayt olduğu için bu spesifikasyona uymadığını unutmayın.)

Lütfen aşağıdaki kurallara ve açıklamalara dikkat edin:

  • Her zamanki quine kuralları geçerlidir, yani programınız kendi kaynak koduna doğrudan erişmesine izin verecek dil özelliklerini kullanamaz.
  • Yinelenen çıkışlar sonunda tam olarak orijinal kodunuza geri dönmelidir ve bunun için bir gösteri veya kanıt eklemeniz gerekir.
  • Ayrıca, döngünün neden söylediğiniz kadar uzun olduğunu açıklamanız gerekir. Bunun matematiksel bir kanıt düzeyinde olması gerekmez, ancak dilinizi bilen birine ikna edici olmalıdır. (Bu kural burada çünkü bazı cevapların çok, çok büyük rakamlar içermesini bekliyorum.)
  • En azından bu kadar uzun olduğunu kanıtlayabildiğiniz sürece, tam sayıyı vermek yerine "en az 1.000.000 yineleme" gibi bir şey söylemek iyidir. Bu durumda puanınız 1.000.000 olur. Aksi takdirde, puanınız quine döneminizdir.
  • 100 bayt limiti yalnızca ilk programınız için geçerlidir - çıktı aldığı programlar daha uzun olabilir, ancak elbette orijinal kodunuzu çıkarmak için sonunda 100 bayta geri dönmeleri gerekecektir.
  • Makinenizin sonsuz RAM ve sonsuz çalışma zamanı olduğunu varsayabilirsiniz, ancak dilinizde yoksa sınırsız hassas veri türü (tamsayı gibi) kabul edemezsiniz. Sen edebilirsiniz senin ayrıştırıcı işleyebilir girdi uzunluğuna sınırlama yoktur varsayalım.
  • En yüksek puan kazanır.

Lütfen dikkat: Quit Whining adında mevcut bir zorluk var ; Yineleme işlemlerini de içeren Quining'i başlatın. Ancak, aynı konsepte dayanmanın yanı sıra, bunlar tamamen farklı zorluk türleridir. Diğeri düz kod golf, oysa bu (kasıtlı olarak!) Gerçekten kılık değiştirmiş meşgul bir kunduz sorunu. Bu soruya iyi bir cevap üretmek için gerekli tekniklerin diğer soruya cevap vermek için gerekenden çok farklı olması muhtemeldir ve bu tasarım gereğidir.


1
@LeakyNun Siz mi yoksa cevabınızı silmiş bir mod mu bilmiyorum, ama belki de neyin yanlış olduğunu açıklarsam bunun neden bir kopya olmadığını anlayacaksınız. Bu soru kaynak uzunluğu için 100 baytlık bir sınır belirler, bu nedenle bu yöntemi kullanarak "istediğiniz kadar yüksek" gidemezsiniz. Bu sorunun bütün mesele bu. Cevaplamak için yapmanız gereken 100 karaktere uyan en uzun sürümü yayınlamak ve süresinin ne olduğunu söylemek. Gönderdiğiniz şey iyi bir ilk denemedir, ancak kazanan olması pek olası değildir.
Nathaniel

1
@ Zorluk tam olarak az sayıda baytta çok sayıda belirtmektir, evet. Etrafında tasarlanan tüm ilke budur. Soru şudur: 3 ^ ^ ^ 3 kendi dilinizde 100 baytta belirtebileceğiniz en yüksek sayı mı yoksa daha büyük bir tane var mı? Bu zorluk budur. Bunun özü. İnsanların gördüklerini görmek istedim. Bu yapının hiçbir şeyi olmayan bir mücadeleye yüzeysel bir benzerlik temelinde kapanması süper, süper sinir bozucu.
Nathaniel

1
@Dave (ikinci yorum) ancak akıllıysanız, makine hassasiyeti ile sınırlı olmanız gerekmez. Rekabetçi cevapların 2 ^ (2 ^ 64) 'den daha uzun bir süreye sahip olmasını beklerim.
Nathaniel

3
Peki bunun codegolf.stackexchange.com/q/18028/194 kopyası olarak kapatılmasını tercih eder misiniz ?
Peter Taylor

1
@PeterTaylor çok daha yakın bir tema, ama yine de çok farklı bir meydan okuma - bir sayı yazdırmak çok sayıda şey yapmaktan oldukça farklı. Tabii ki hiç kapatılmamasını tercih ederim.
Nathaniel

Yanıtlar:


10

PHP, dönem 2.100.000.000

PHP'de bunun mümkün olduğunu kim düşünebilirdi ki ?! :-)

Bu aslında benim ilk quine'm ve 99 byte uzunluğunda:

<?$i=1;$i*=21e8>$i;printf($a='<?$i=%d;$i*=21e8>$i;printf($a=%c%s%c,++$i,39,$a,39);',++$i,39,$a,39);

PHP, 2 * 10^8geçiş yapmaktan daha büyük sayıları desteklese integerde double, artış artık çalışmıyor (sonsuz bir döngüye yol açıyor) ve 100 bayta sığacak başka bir çözüm bulamadım. Hala.

İspat oldukça basittir, çünkü 2.1 milyarda sıfırlama noktasına ulaşana kadar her yinelemeye güvenir.

İçin Kredi dave yorumlarda ve sözde kod yaklaşımı yayınlanmıştır, Bob Twells ben minimal bir PHP Quine'a kodu kopyalanan aldığınız.

Test programı (sloooooow):

<?php
$o = file_get_contents('quine.php');
for ($i = 0; $i < 22e8; $i++) {
    if ($i%2==0) exec('php q > p'); else exec('php p > q');
    $a = file_get_contents(($i%2==0) ? 'p' : 'q');
    echo "\r" . str_pad($i,6,' ') . ":\t$a";
    if ($a == $o) {
        die;
    }
}

En azından ilk cevaplayan benim.


1
Yan not: Bu ~ 10 ^ 9.322219295 mertebesindedir.
LegionMammal978

8

Mathematica, dönem E8.5678 # 3 E2.1923 # 4 ~ E6.2695 # 3 # 2

Print[ToString[#0, InputForm], "[", #1 - 1 /. 0 -> "Nest[#!,9,9^9^99!]", "]"] & [Nest[#!,9,9^9^99!]]

Skorların Hyper-E notasyonunda açıklandığını unutmayın . Yinelemeler finali - 1, - 2, - 3, ..., 3, 2, 1 Nest[#!,9,9^9^99!]ondalık açılımları ile değiştirir ve geri dönerler .Nest[#!,9,9^9^99!]Nest[#!,9,9^9^99!]Nest[#!,9,9^9^99!]Nest[#!,9,9^9^99!]


faktöriyeliler daha hızlı büyümez mi?
Maltysen

1
Mathematica bilmiyorum, ama bu bir quine için kuralların ihlali değil - kendi kaynak kodunu okumak? ToString[#0, InputForm]
daniero

yani, sadece 9 !!!! çalışmıyor mu? idk çünkü şu an matematiksel rpi'm yok.
Maltysen

@Maltysen Bu dokuz, veya (9 !!) çift faktöriyel çift faktöriyel hesaplar !! ≈ 2.116870635 · 10¹²⁰²
LegionMammal978

@daniero Yani, fikir standart bir CJam benzer {"_~"}_~, bu yüzden geçerli olması gerektiğini düşünüyorum ...
LegionMammal978

5

R, beklenti ile rastgele dönem 2 ^ 19936-0.5

f=function(){
    options(scipen=50)
    body(f)[[4]]<<-sum(runif(623))
    0
    cat("f=")
    print(f)
}

R'nin varsayılan rasgele sayı üreteci 2 ^ 19937-1 periyoduna ve ardışık 623 boyutta eşit dağıtıma sahiptir. Böylece, döneminde bir yerde (sadece bir kez) 623 uzunluğunda bir sıfır vektörü olacaktır. Oraya vardığımızda (ve dizinin başlangıcıyla hizalandığımızda) sonraki 623 rastgele U [0,1] sayısının toplamı sıfır olacak ve orijinal programımıza döneceğiz.

Çok yüksek olasılıklı programın sıfıra dönmeden önce birkaç kez aynı sıfır olmayan durumdan geçeceğini unutmayın. Örneğin, toplam 311.5 en olasıdır ve gerçekleşebilecek birçok yol vardır, ancak RNG, 0 periyodunun 311.5 döneminden daha uzun olmasına izin verir.


Bu girişe hangi puanı atamak istediğinizden emin değilim: P
JDL

1
Kurallara göre: "Tam sayıyı vermek yerine" en az 1.000.000 yineleme "gibi bir şey söylemek iyi, bence bu" en az 1 yineleme "çünkü ilk denemede gerçekten şanslı olursak ...;)
YetiCGN

“Bazı rastgele girdiler üretebilirim, cevap orada” gibi birçok standart boşluktan farklı olarak, bu kesin cevabın oluşmaya bağlı olduğunun ve çok iyi bir tahminin verildiğinin gerçekten düzgün bir kanıtıdır. Güzel!
Andreï Kostyrka

1
Program bir kez temel durumuna döndüğünde, rastgele olmayan bir tam olarak 2 ^ 19937-1 süresine sahip olacaktır.
JDL

Bunun çıktısı gerçek programla eşleşmiyor (biraz boşluk eksik). Ayrıca, program çağrıları arasında devlet korunmayacaktır, bu nedenle dönem tam bir sayı olmayacak ve tutarlı olmayacaktır
Jo King

1

JavaScript, dönem 9.007.199.254.700.000

Kazanmayacak, ancak bu meydan okumada JavaScript ile çalışmak eğlenceliydi:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)

Aşağıdaki döngüyü izler:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699999-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699998-1||90071992547e5)
// etc...
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),3-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),2-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
// and so on

Not: Puanın yalnızca ~% 0,08'ini kaldırırken, 18 bayt daha kısa yapabilirsiniz:

a="a=%s;console.log(a,uneval(a),%.0f-1||9e15)";console.log(a,uneval(a),1-1||9e15)

1

C, dönem 2.100.000.000

unsigned long long i;main(a){i=1;i*=21e8>i;printf(a="ungisned long long i;main(a){i=%d;i*=21e8>i;printf(a=%c%s%2$c,++i,34,a);}",++i,34,a);}

PHP cevabına dayanarak (belli ki). Zamanım olduğunda açıklama ile güncellenir.


1

C (gcc) , 66 bayt, nokta 2 ^ 64

f(s){printf(s="f(s){printf(s=%c%s%1$c,34,s,%lu+1L);}",34,s,0+1L);}

Çevrimiçi deneyin!

2 ^ 64 sayı bir unsigned longtamsayıda mevcuttur . Bu nedenle, 2 ^ 64'lük bir süre.


1

Python 2

Dönem: 9((99↑↑(9((99↑↑(9((99↑↑(9↑↑51))9)1))9)1))9)+1

@Bubbler, 99(99↑↑12)+1 şimdiye

b=0;s="print'b=%d;s=%r;exec s'%(-~b%eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9))),s)";exec s

Çevrimiçi deneyin!

Kodda, daha sonra ve daha sonra yapılan b=0değişiklikler ,b=1b=2b=decimal expansion of the periodb=0


1
9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9daha yüksek 9**9**99**99**99**99**99**99**99**99**99**99**99**99. Bununla birlikte, eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9)))çok daha yüksek sayılar için bir şey yapabilirsiniz .
Bubbler

Peroid anlamı ne?
SS Anne

@SSAnne, Knuth'un yukarı ok gösterimi
Mukundan

1
@Mukundan Sanırım dönem demek isteyebilirsiniz ama emin değilim. Tetrasyonun ne olduğunu anlıyorum.
SS Anne

Ne yazık ki bir yazım hatasıydı, işaret ettiğiniz için teşekkürler
Mukundan

0

Göl> <> , 70 bayt, dönem 325883196621297064957600206175719056476804879488288708188003274919860959534770101079512433396348062803055739640225395758790852315876868469390603793729639715908136196505908165227136154287969475839017544811926036808089596209081885772040898530121921794489026069641113281250

Diğer bilge gerçekten büyük olarak bilinir (3.25E270)

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||lPffXfX=?1:1=Q$~$~|:1)lPffXfX(Q?:|r2ssH##

Bu aslında 500 bayt yineleyiciye koyduğum cevabın değiştirilmiş bir versiyonu

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||//if last is equal to 1 and length is 71, delete the delete char, if the last char is '~', delete and push 'H#', which will later return to 'H##', completing the cycle!
lPffXfX=?1:1=Q$~$~|          //if length is equal to 15^15^15, then start delete process(append ascii one)
:1)lPffXfX(Q?:|              //if the last character is not 1 (the delete checker), and length is less than 15^15^15, duplicate the last value and append
r2ssH##                      //push the " to the front and output the whole thing

İnşallah skoru doğru buldum ve hiçbir hata yok. Bu değeri gerçekten hesaplamanın gerçek bir yolu yoktur , teoriktir. Ama adamım, bu çok büyük bir sayı !!!

Çevrimiçi deneyin!

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.