Entropik Kın!


12

Göreviniz bir program veya işlev yazmaktır:

  • İlk kez çalıştırıldığında, kaynak kodunu çıkarır.
  • Sonraki yürütmelerde, daha önce çıkardıklarının çıktısını almalıdır, ancak bir rastgele karakter değişikliği ile (aşağıda tanımlanmıştır). Tekdüze rastgele bir değişiklik olması gerekmez, ancak olası her değişikliğin sıfır olmayan bir gerçekleşme şansı olmalıdır.

    İlk İdamdan sonra, programınız olacak değil mutlaka artık Quine olmak; çıktı değişmiş olacaktır (ve program da kendisini değiştirmekte serbesttir).

Örneğin, sorgunuz ABCDtekrar tekrar çalıştırıldıysa yazdırılabilir:

ABCD
A!CD
j!CD
j!CjD

Özellikler

  • Karakter değişikliği:

    • Rastgele bir karakterin eklenmesi,
    • Rastgele bir karakterin silinmesi veya
    • Bir karakterin yeni bir rastgele karakterle değiştirilmesi. Yeni karakterin değiştirdiği karakterle aynı olmasına izin verilir, bu durumda değişiklik yapılmaz.

    Tabii ki, boş bir dizeden bir karakteri silmek veya değiştirmek geçerli bir değişiklik değildir.

  • Bu etiketlenmiş rağmen , kaynak kodunuzu okumaya karşı kurallar geçerli değildir.

Kaynak kodunuzda kullanılan karakterleri içerdiği sürece herhangi bir karakter setini kullanabilirsiniz.


1
Her karakter hangi karakterleri ifade eder?
Dennis

2
Bunun ne sıklıkla çalışması gerekiyor? Açıkçası, keyfi olarak orijinal programdan daha uzun veya daha uzun olası her program zorlukla bir çözüm olmak zorunda değildir.
Martin Ender

1
Karakter herhangi bir yere veya sadece sonuna eklenebilir mi?
Conor O'Brien

1
@ ConorO'Brien Anywhere.
Esolanging Fruit

1
Kaç tane yineleme çalışması gerekiyor?
dylnan

Yanıtlar:


7

Python 3 , 288 270224421219619619480178168 bayt

f=__file__
m=open(f).read()
x=m	
print(end=x)
h=hash
k=h(f)
n=k%2
a=h(m)%-~len(x)
x=x[:a]+(not(k%3)*x)*chr(k%127)+x[a+n:]
open(f,'w').write(m.replace("\t",";x=%r\t"%x))

Çevrimiçi deneyin!

İlk yinelemede dosya kaynak kodunu yazdırdıktan sonra, x'i m yerine yeni kaynak koduna ayarlamak için fazladan bir satır ekliyoruz.

Açıklama:

f=__file__    #Open and read the source code
m=open(f).read()

x=m       #Set x to the source code for the first iteration
x="..."
...
x="..."   #Set x to the latest iteration
          #On the last iteration there's a tab character to mark progress
print(end=x)    #Print the previous iteration's text

#Modify the text
h=hash
k=h(f)            #Generate a random number to use
n=k%2             #Whether the character will be inserted or changed/deleted
a=h(m)%-~len(x) #The index of the change
                         #Add 1 to the range to append new characters, and to avoid mod by 0 in the case of an empty string
x=x[:a]+(not(k%3)*x)*chr(k%127)+x[a+n:]    #Make the change

open(f,'w').write(m.replace("\t",";x=%r\t"%x))   #Modify the source code, adding the new iteration of the source code

hashDüzgün rasgele bir sayı döndürdüğünü varsayarsak , yeni bir karakter eklemek için yaklaşık 1/6, mevcut bir karakteri değiştirmek için 1/6 ve bir karakteri silmek için 2/6 şans vardır. Geriye kalan 2/6 şansınız nedir? Neden, hiçbir zaman 2/6 hiçbir şey yapmaz!

(İşte mbomb007'nin cevabından uyarlanmış bir doğrulama programı . Çevrimiçi deneyin! )


f=__file__İlk adımda da yardımcı olacağını düşünüyorum .
Ørjan Johansen

4

Python 3 , 205195 bayt

s='print(end=x);h=hash;k=h(x);n=k%2;a=h(s)%-~len(x);x=x[:a]+(not(k%3)*x)*chr(k%127)+x[a+n:];open(__file__,"w").write("s=%r;x=%r;exec(s)"%(s,x))';x='s=%r;x=%r;x=x%%(s,x);exec(s)';x=x%(s,x);exec(s)

Çevrimiçi deneyin!

Kaynak kodunu okumayan bir sürümü denemek istedim. Düşündüğüm gibi değil kötü çıktı ve sadece 30 ya da öylesine arkasında bayt var sürümü yapar . Nasıl çalıştığına dair açıklama çoğunlukla diğer cevapla aynıdır, ancak kaynak kodunu okuyamayacağı için x'i farklı şekilde başlatır.


4

Python 2 , 779801 bayt

Her ne kadar meydan okuma, kaynağınızı okumanıza izin verildiğini göstermek için düzenlenmiş olsa da, zaten bu olmadan çözümümü oluşturuyordum. Yani, mümkün olduğunu göstermek için bitirdim. Kaynak dosya okunmuyor:

s='s=%r;print s%%s\nfrom random import*;L=4;f=open(__file__,"wa"[L>5]);R=randint\nf.write("\\n".join((s%%s).split("\\n")[1:5:2]).replace("4",`map(ord,s%%s)`))\nif L>5:exec\'b=[];h=%%d\\nwhile~-h:b+=[h%%%%1000];h/=1000\\nwhile b:r,p,n=b[-3:];b=b[:-3];L=[L[:p]+L[p+1:],L[:p]+[r]+L[p+n:]][n<2if L else 1]\\nprint"".join(map(chr,L))\'%%1\n\nn=R(0,2);p=R(0,len(L if L>5else s%%s));r=R(0,255);f.write("%%03d"*3%%(n,p,r))';print s%s
from random import*;L=4;f=open(__file__,"wa"[L>5]);R=randint
f.write("\n".join((s%s).split("\n")[1:5:2]).replace("4",`map(ord,s%s)`))
if L>5:exec'b=[];h=%d\nwhile~-h:b+=[h%%1000];h/=1000\nwhile b:r,p,n=b[-3:];b=b[:-3];L=[L[:p]+L[p+1:],L[:p]+[r]+L[p+n:]][n<2if L else 1]\nprint"".join(map(chr,L))'%1

n=R(0,2);p=R(0,len(L if L>5else s%s));r=R(0,255);f.write("%03d"*3%(n,p,r))

Çevrimiçi deneyin! (Bunun kaynağı değiştirmeyeceğini unutmayın. Bunun çalışması için yerel olarak çalıştırmanız gerekir)

Dönüşümleri, burada çalışan olduğunu göstermek için bir olan test programı (şu anda her zaman almaya kurmak 100için r, ve her kombinasyon için sonuç yazdırır nve pilk liste için.)



Açıklama:

s='s=%r;print s%%s...';print s%s...

İlk satır klasik kininiz, ancak sonra gelenleri açıklamak için çok daha uzun.

from random import*;L=4;f=open(__file__,"wa"[L>5]);R=randint

Rastgele tamsayılar için içe aktarın. Lkaynak kodun sıra sıralarının bir listesi haline gelir, ancak başlangıçta bir dizenin değiştirilmesine izin vermek için kaynağın başka hiçbir yerinde kullanılmayan bir tamsayıdır. Yeni kaynağı yazmak için dosyayı açın. Daha sonraki çalışmalarda, bunun yerine eklemek için açılır.

f.write("\n".join((s%s).split("\n")[1:5:2]).replace("4",`map(ord,s%s)`))

Birinci ve üçüncü kod satırlarını kaldırın. 4Yukarıdakileri sıra sayıları listesiyle değiştirin .

if L>5:exec'b=[];h=%d\nwhile~-h:b+=[h%%1000];h/=1000\nwhile b:r,p,n=b[-3:];b=b[:-3];L=[L[:p]+L[p+1:],L[:p]+[r]+L[p+n:]][n<2if L else 1]\nprint"".join(map(chr,L))'%1

n=R(0,2);p=R(0,len(L if L>5else s%s));r=R(0,255);f.write("%03d"*3%(n,p,r))

Parçalar halinde:

  • if L>5:- İlk yürütmede bu satırı atlar. Daha sonra, Lbir liste olacak ve bu çalışacaktır. Sonuncuyu açıklayacağım exec, çünkü ilk kez çalışmaz.

  • n- Rasgele bir sayı 0-2. Bu, hangi değişikliğin gerçekleşeceğini belirler (0 = ekleme, 1 = değiştirme, 2 = silme).

  • p - Değişikliğin yapılacağı listede rastgele bir konum.

  • r - Listeye eklemek veya listeye eklemek için rastgele bir sayı

  • f.write("%03d"*3%(n,p,r))- 3 rasgele kaynak dosyanın sonuna ekleyin. Her çalıştırmada, meydana gelen ilk kaynaktaki tüm değişiklikleri kodlayan bir tam sayı eklenir.

  • exec'b=[];h=%d...'%1...- Rastgele sayıları alın ( %1sonraki çalışmalarda bulunur), değişiklikleri listeye uygulayın ve yazdırın.

  • while~-h:b+=[h%%1000];h/=1000- Öncüleri oluşturan ve önde 1gelen sıfırlarla ilgili sorunları önleyen, şimdiye kadar üretilen rastgele bir liste oluşturun .

  • while b:r,p,n=b[-3:];b=b[:-3] - Bu yineleme için rastgele atayın.

  • L=[L[:p]+L[p+1:],L[:p]+[r]+L[p+n:]][n<2if L else 1] - (0 = ekle, 1 = değiştir, 2 = sil)

  • print"".join(map(chr,L)) - Değiştirilen kaynağı yazdırın.


Bu bazen varolmayan bir karakteri dizenin sonundan silebilir mi? Çünkü pipin uzunluğu olabilir. Ayrıca, boş bir dize ile davranış nedir?
Jo King

@ JoKing Bir test programı ekledim. Her olası karakter değişikliği olabilir. Yalnızca bir ekleme, değiştirme veya silme için her konumun seçilebildiğini ve boş bir listeyi işlediğini gösterir. tio.run/##LYoxDsMgDEVnOAUjCAZgRO0NuIHloUOaRIocy6JDT08dpdt/…
mbomb007

OP'ye sorduğum halde hiçbir değişikliğin geçerli olduğunu düşünmüyorum. Soru diyorOf course, deleting or replacing a character from an empty string is not a valid change
Jo King

Ben Esolanging Fruit sordunuz ve onlar hiçbir değişiklik demek olduğunu ancak boş bir dize, geçerli.
Jo King

1
@JoKing Düzeltilmelidir.
mbomb007

1

Java 10, 370 bayt

String s;v->{if(s==null){s="String s;v->{if(s==null){s=%c%s%1$c;s=s.format(s,34,s);}else{int r=s.length();r*=Math.random();char c=127;c*=Math.random();s=s.substring(0,r)+(c%%3<2?c:%1$c%1$c)+s.substring(r+(c%%3>0?1:0));}}";s=s.format(s,34,s);}else{int r=s.length();r*=Math.random();char c=127;c*=Math.random();s=s.substring(0,r)+(c%3<2?c:"")+s.substring(r+(c%3>0?1:0));}}

Çevrimiçi deneyin.

Açıklama:

String s;               // Class-level String variable to store the modifying source code
v->{                    // Method without parameter nor return-type
  if(s==null){          //  If this is the first execution of this function:
    s="String s;v->{if(s==null){s=%c%s%1$c;s=s.format(s,34,s);}else{int r=s.length();r*=Math.random();char c=127;c*=Math.random();s=s.substring(0,r)+(c%%3<2?c:%1$c%1$c)+s.substring(r+(c%%3>0?1:0));}}";
                        //   Set `s` to the unformatted source-code
    s=s.format(s,34,s);}//   And then to the formatted source-code
else{                   //  For any following executions of this function:
  int r=s.length();r*=Math.random();
                        //   Random index in range [0, length_of_modified_source_code)
  char c=127;c*=Math.random();
                        //   Random ASCII character in unicode range [0, 127)
  s=                    //   Replace the current String `s` with:
    s.substring(0,r)    //    The first [0, `r`) characters of the modified source code `s`
    +(c%3<2?            //    If the random option is 0 or 1:
           c:"")        //     Append the random character
        +s.substring(r  //    Append the rest of the modified source code `s`, but:
          +(c%3>0?      //     If the random option is 1 or 2:
             1:0));}}   //      Skip the first character of this second part

Genel açıklama:

-part:

  • Dize s, biçimlendirilmemiş kaynak kodunu içerir.
  • %s, bu Dizeyi ile içine girmek için kullanılır s.format(...).
  • %c, %1$cve 34çift ​​tırnakları biçimlendirmek için kullanılır.
  • ( %%modulo- formatlamak için kullanılır %).
  • s.format(s,34,s) hepsini bir araya getirir.

Burada temel bir Java quine programı.

Zorluk bölümü:

  • String s; sınıf düzeyinde değiştireceğimiz kaynak kodudur.
  • int r=s.length();r*=Math.random();aralıktaki kaynak kodun rastgele bir dizinini seçmek için kullanılır [0, length_of_modified_source_code).
  • char c=127;c*=Math.random();unicode aralığında rastgele bir ASCII karakteri (yazdırılamayanlar dahil) seçmek için kullanılır [0, 126].
  • c%30, 1 veya 2'den rastgele bir seçenek seçmek için kullanılır. Seçenek 0, dizinden önce rastgele karakteri ekler r; seçenek 1, dizindeki rkarakteri rastgele karakterle değiştirir; ve 2. seçenek dizindeki karakteri kaldırır r.
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.