Yavaş büyüyen Quine


30

Bir Quine yap.

Kolay doğru görünüyor? Eh, bu quine kendisini artı ilk karakterini, sonra kendisini ikinci karakterini ve benzeri çıktılar.

Bu şekilde quine birkaç nesilde iki kopya çıkarmalıdır.

Örnek: Kodunuzun olmasını sağlar x. Çalıştırılması çıktı gerekir x + x[:1]. Elde edilen programın çalıştırılması çıktı vermelidir x + x[:2]ve böylece ...

Eğer kodunuz buysa foobar, bunu çalıştırmanız gerekir foobarf. Bunu çalıştırmak çıktı vermelidir foobarfo. Ve bu deseni izleyerek devam ediyoruz:

foobar
foobarf
foobarfo
foobarfoo
foobarfoob
foobarfooba
foobarfoobar
foobarfoobarf

Programınız 2 Bayttan daha uzun olmalı ve her yinelemede yalnızca kendi kodunun yalnızca BİR ekstra karakteri çıkarmalıdır.


3
Kaynak kodun varsayılan olarak okunmasının yasak olduğu düşünüldüğünde, bu zorluğun çoğu dilde imkansız olduğundan şüpheleniyorum.
Ørjan Johansen

12
@ ØrjanJohansen ve daha sonra Dennis ortaya çıkıyor
Rod

2
@Rod Pekala , hepsini söylemedim , sadece / birçok dilin isteğe bağlı kod parçalarını sonuna kadar eklemek için hiçbir yolu yoktur, öyle ki (1) bir sözdizimi hatası vermez (2) program değişikliği tespit edebilir.
Ørjan Johansen

3
Bu çok sıradışı bir ip olduğu için normal kuaför boşlukları hala yasaklandı mı?
Draconis

Yanıtlar:


15

Zsh ,110 108 100 bayt

a=`<&0`<<''<<<t;b=${a:0:50};printf $b$b${a:0:-50}
a=`<&0`<<''<<<t;b=${a:0:50};printf $b$b${a:0:-50}

Çevrimiçi deneyin!

Bu yüzden mümkün.

açıklama

a=`<&0`<<''<<<t;       # Set A to everything following this line, until eof or
                       #   an empty line (which never happens before eof) encountered.
                       # A "t" is appended to prevent automatic trimming of newlines.
b=${a:0:50};           # Set B to the first line.
printf $b$b${a:0:-50}  # Print two copies of B and
                       #   A with 50 trailing characters removed.


11

R, 289 bayt

s<-c("s<-", "i=get0('i',ifnotfound=0)+1;p=paste0(s,substr(get0('p',ifnotfound=s),1,i),collapse='');cat(s[1]);dput(s);cat(paste0(s[2],substr(p,1,i)))#")
i=get0('i',ifnotfound=0)+1;p=paste0(s,substr(get0('p',ifnotfound=s),1,i),collapse='');cat(s[1]);dput(s);cat(paste0(s[2],substr(p,1,i)))#

İlham almak için bu sıranın kredisi . Yalnızca önceki quine ile aynı R ortamında çalıştırıldığında çalışır.


bir açıklama gelecek ... 288 kez test etmedim, ancak oldukça doğru olduğuna ikna oldum
Giuseppe

Bu, 289 byte olmalıydı çünkü quine orada yeni bir çizgi karakteri ekledi, ama yine de çözdün mü!
IQuick 143

ah, haklısın, aptal catnewlines ekleyerek.
Giuseppe,

Ama bu tam bir program mı? Oluşturulan kod dolu programlar mı?
jimmy23013

@ jimmy23013 Söyleyebileceğim kadarıyla, bu cevap ve oluşturulan kod tam programlardır. mainR'de buna benzer başka bir zorunlu yapı yoktur ya da yoktur . Ayrıca, soru açıkça tam bir program istemez, bu nedenle bir işlev ya da benzeri bir şey yapacaktır.
Steadybox

5

Alice , 29 bayt

4P.a+80pa2*&wdt,kd&w74*,.ok@

Çevrimiçi deneyin!

Yazdırılamayan karakter 0x18.

açıklama

Her zamanki "temelli Fungeoid sorguları ile ilgili sorun, kaynak kodun tamamını tekrar edersek, o zaman ayrıca ek alıyoruz "ve dizgenin artık kaynak kodunun tamamını kapsamaması . Var olan cevabın gbunun yerine hile-y yaklaşımını kullandığını düşünüyorum.

Bu cevap "temelli yaklaşımı kullanır, ancak bir "kaynağa dahil etmek yerine çalışma zamanında programa yazarız. Bu şekilde, "programın ne sıklıkta tekrar edildiğine bakılmaksızın yalnızca bir kişi olacak (çünkü programın boyutundan bağımsız olarak, yalnızca belirli bir koordinata yazıyoruz).

Genel fikir, o zaman yığında bütün kaynak kodun bir gösterimini yaratmamızdır, ancak sadece kodun büyüklüğü tarafından belirlenen döngünün uzunluğu ile karakterlerin ilk 29'unda (yani program uzunluğu) dolaşır. Bu nedenle, gerçekte rasgele karakterler (satır satırları hariç) ekleyebiliriz @ve sonuç her zaman temel programın döngüsel bir tekrarıdır, kaynaktan bir karakter daha uzun olacaktır.

4P   Push 4! = 24. This is the code point of the unprintable, which we're 
     using as a placeholder for the quote.
.a+  Duplicate it and add 10, to get 34 = '"'.
80p  Write '"' to cell (8,0), i.e. where the first unprintable is.
    Placeholder, becomes " by the time we get here, and pushes the code
     points of the entire program to the stack. However, since we're already
     a good bit into the program, the order will be messed up: the bottom
     of the stack starts at the 24 (the unprintable) followed by all 
     characters after it (including those from extraneous repetitions). Then 
     on top we have the characters that come in front of the `"`. 
     So if the initial program has structure AB, then any valid program has
     the form ABC (where C is a cyclic repetition of the initial program),
     and the stack ends up holding BCA. We don't care about C, except to
     determine how big the program is. So the first thing we need to do is
     bring B to the top, so that we've got the initial program on top of
     the stack:
a2*  Push 10*2 = 20.
&w   Run the following section 21 times, which is the length of B.

  dt,  Pull up the value at the bottom of the stack.

k    End of loop.
d&w  Run the following section D+1 times, where D is the length of ABC.

  74*  Push 28, one less than the number of characters in AB.
  ,    Pull up the 29th stack element, which is the next character to print.
  .o   Print a copy of that character.

k    End of loop.
@    Terminate the program.

Harika bir çözüm. Açıklamayı seviyorum.
IQuick 143

4

Perl 5 , 83 bayt (son satırsonu dahil)

$_=q($/=$;;$_="\$_=q($_);eval
__END__
".<DATA>;print$_,/(.).{82}\z/s);eval
__END__

Çevrimiçi deneyin!

İyi bir __DATA__belirteç , herhangi bir Perl programına isteğe bağlı bir dize eklemeyi kolaylaştırır, ana program daha sonra <DATA>dosya tanıtıcısı aracılığıyla erişebilir (ve aslında __END__, __DATA__iki ekstra bayt yerine geriye doğru uyumluluk için aynı şeyi yapan ) .

Bu program olmadığını Not değil , kendi kaynak kodunu okumak, ama sadece ekstra girdi verileri sonra kaynağına eklenen __END__belirteç. Sonuç olarak, __END__token ve ondan sonraki her şey, girişin sonuyla biten bir dizgenin benzeri gibi çalışır.

Ayrıca, spesifikliği tam olarak karşılamak için bu programın yeni bir satırda bitmesi gerektiğini unutmayın. Olmazsa, yeni satır __END__zaten ikinci işlemden sonra otomatik olarak eklenir , ancak daha sonra ilk yineleme çıkışı tam olarak koda ve ilk baytına tam olarak eşit olmaz.


2

Befunge-98 , 30 bayt

0>:#;0g:840#;+*#1-#,_$a3*%0g,@

Çevrimiçi deneyin!

Boşluk sonlu bir kın kullanılan Befunge-98'i kullanmaya çalıştığımda, kaç karakterin çıktılandığını da sayarım. Ancak gkomutu kullanıyor mu .


İlk satırda rekabet etmediğini / aldatma olduğunu belirtmek isteyebilirsiniz, aksi takdirde elde edilebilecek herhangi bir indirimi reddetmek için.
quintopia

2

PHP, 146 bayt

ob_start(function($s){return($u=substr($s,0,73)).$u.substr($s,0,-72);})?>ob_start(function($s){return($u=substr($s,0,73)).$u.substr($s,0,-72);})?>

-rKomut satırında kullanılarak çalıştırılmalıdır .


Çevrimiçi denediğimde çalışmıyor gibi görünüyor ! , sadece sıradan bir sırt.
Ørjan Johansen

@ ØrjanJohansen Birlikte çalıştırmalısınız php -r 'command'.
jimmy23013

Gah, işe yaramadı. TIO sadece -r argümanlarını görmezden geliyor gibi görünüyor.
Ørjan Johansen


Aha. O zamanlar bir şeyi yanlış anlamış olmalıyım. Şimdi PHP ile de dil ayarı olarak çalışmayı başardım .
Ørjan Johansen

2

Runik Büyüleri , 61 bayt

803X4+kw.'.q}͍}͍}͍}͍}͍}͍}͍}͍}͍::l͍5X-:}-$:l͍{-1--@

Çevrimiçi deneyin!

Alice'in cevabına benzer bir yaklaşım kullanır: string "komutunu yansıtıcı biçimde kod yazar, böylece One One vardır. Dinlenme, orijinal programı kurtarmak için kaç tane fazla bayta ihtiyaç duyulduğunu ve gerekli parçaların basılmasını sağlayan çok sayıda dize ve yığın manipülasyonudur.

Dizisi etrafında çok bellek dizge gösterimini dönecek şekilde 803X4+kwgörünür nedeniyle pozisyonuna yerine sonunda başlangıç "ve hantal bir sayı çok hesaplamak zorunda kalmadan bu işlemi işleme daha kolay bir yolu yoktur .

Orijinal programı 61 iken bayt onun dize uzunluğu yalnızca yapı kolaydır 50 olduğu 5X, örneğin bir uzunluk 49 programı daha kolay olurdu (ve bu gerekli tüm işlevselliği içeren sonra yastıklı olması gerek yoktu sadece tesadüf olarak kodlamak için 50bir hazır kodlamak için birden dolgu biri byte ile 49ederken, 51olarak kodlanmış olacağını 5X3+veya 53), kendi ekstra bayt için hesaba sahip.

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.