Entropic Quine!

12

Tugas Anda adalah menulis program atau fungsi yang:

  • Saat dijalankan untuk pertama kalinya, mengeluarkan kode sumbernya.
  • Pada eksekusi berikutnya, ia harus menampilkan apa yang dihasilkan sebelumnya, tetapi dengan satu perubahan karakter acak (didefinisikan di bawah). Itu tidak harus menjadi perubahan acak yang seragam, tetapi setiap perubahan yang mungkin harus memiliki peluang bukan nol terjadi.

    Setelah eksekusi pertama, program Anda tidak lagi menjadi quine; output akan berubah (dan program bebas untuk memodifikasi sendiri juga).

Misalnya, jika quine Anda adalah ABCD, menjalankannya berulang kali dapat mencetak:

ABCD
A!CD
j!CD
j!CjD

Spesifikasi

  • Perubahan karakter adalah:

    • Penyisipan karakter acak,
    • Penghapusan karakter acak, atau
    • Penggantian karakter dengan karakter acak baru. Perhatikan bahwa karakter baru diizinkan sama dengan karakter yang digantikannya, dalam hal ini tidak ada perubahan yang akan dilakukan.

    Tentu saja, menghapus atau mengganti karakter dari string kosong bukanlah perubahan yang valid.

  • Meskipun ini ditandai , aturan yang melarang membaca kode sumber Anda tidak berlaku.

Anda dapat menggunakan set karakter apa pun asalkan mencakup karakter yang digunakan dalam kode sumber Anda.

Buah Esolanging
sumber
1
Apa karakter yang dimaksud setiap karakter ?
Dennis
2
Seberapa sering ini harus bekerja? Jelas itu tidak dapat secara sewenang-wenang atau sebaliknya setiap program yang mungkin lebih lama atau lebih lama dari yang asli harus menjadi solusi untuk tantangan.
Martin Ender
1
Bisakah karakter ditambahkan di mana saja, atau hanya di akhir?
Conor O'Brien
1
@ ConorO'Brien Anywhere.
Buah Esolanging
1
Berapa banyak iterasi yang harus dijalankan?
dylnan

Jawaban:

7

Python 3 , 288 270 224 212 195 196 194 180 178 168 byte

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

Cobalah online!

Setelah mencetak kode sumber file pada iterasi pertama, kami menambahkan baris tambahan untuk mengatur x ke kode sumber baru, daripada m.

Penjelasan:

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

Dengan asumsi hashmengembalikan nomor acak yang seragam, ada sekitar 1/6 peluang memasukkan karakter baru, 1/6 peluang mengubah karakter yang ada dan 2/6 peluang menghapus karakter. Berapa sisa 2/6 kesempatan yang Anda tanyakan? Mengapa, itu tidak melakukan apa-apa 2/6 waktu!

(Berikut adalah program validasi yang diadaptasi dari jawaban mbomb007 . Coba online! )

Jo King
sumber
Saya pikir f=__file__akan membantu pada langkah pertama juga.
Ørjan Johansen
4

Python 3 , 205 195 byte

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)

Cobalah online!

Ingin mencoba versi yang tidak membaca kode sumber. Ternyata tidak seburuk yang saya kira, dan hanya 30 atau lebih byte di belakang versi yang melakukannya . Penjelasan untuk cara kerjanya sebagian besar sama dengan jawaban yang lain, tetapi ia menginisialisasi x berbeda karena tidak bisa hanya membaca kode sumber.

Jo King
sumber
4

Python 2 , 779 801 byte

Meskipun tantangan telah diedit untuk menunjukkan bahwa membaca sumber Anda diperbolehkan, saya sudah membuat solusi tanpa itu. Jadi, untuk menunjukkan bahwa itu mungkin, saya menyelesaikannya. Tidak ada pembacaan file sumber:

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

Cobalah online! (Perhatikan bahwa ini tidak akan mengubah sumber. Anda harus menjalankannya secara lokal agar dapat berfungsi)

Untuk menunjukkan bahwa transformasi bekerja, di sini adalah program uji (saat ini dibentuk untuk selalu memilih 100untuk r, dan mencetak hasil untuk setiap kombinasi ndan puntuk daftar awal.)



Penjelasan:

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

Baris pertama adalah quine klasik Anda, tetapi lebih lama untuk menjelaskan apa yang terjadi setelahnya.

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

Impor untuk bilangan bulat acak. Lakan menjadi daftar tata cara kode sumber, tetapi pada awalnya merupakan bilangan bulat yang tidak digunakan di tempat lain dalam sumber untuk memungkinkan penggantian string. Buka file untuk menulis sumber baru. Pada menjalankan selanjutnya, itu akan terbuka untuk menambahkan.

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

Hapus baris kode pertama dan ketiga. Ganti yang di 4atas dengan daftar tata cara.

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

Dalam potongan:

  • if L>5:- Melewati baris ini pada eksekusi pertama. Nantinya, Lakan ada daftar, dan ini akan berjalan. Saya akan menjelaskan yang execterakhir, karena ini tidak berjalan pertama kali.

  • n- Angka acak 0-2. Ini menentukan modifikasi yang terjadi (0 = masukkan, 1 = ganti, 2 = hapus).

  • p - Posisi acak dalam daftar tempat modifikasi akan terjadi.

  • r - Nomor acak untuk dimasukkan atau diganti dalam daftar

  • f.write("%03d"*3%(n,p,r))- Tambahkan 3 tebusan ke akhir file sumber. Setiap kali dijalankan, ini akan menambahkan bilangan bulat yang menyandikan semua perubahan ke sumber awal yang telah terjadi.

  • exec'b=[];h=%d...'%1...- Dapatkan nomor acak (ditemukan setelah %1dijalankan nanti), terapkan perubahan pada daftar, dan cetak.

  • while~-h:b+=[h%%1000];h/=1000- Buat daftar tebusan yang dihasilkan sejauh ini, yang bertanggung jawab atas yang memimpin 1, yang mencegah masalah dengan angka nol di depan.

  • while b:r,p,n=b[-3:];b=b[:-3] - Tetapkan tebusan untuk iterasi ini.

  • L=[L[:p]+L[p+1:],L[:p]+[r]+L[p+n:]][n<2if L else 1] - (0 = masukkan, 1 = ganti, 2 = hapus)

  • print"".join(map(chr,L)) - Cetak sumber yang dimodifikasi.

mbomb007
sumber
Apakah ini terkadang menghapus karakter yang tidak ada dari akhir string? Karena pbisa menjadi panjang senar. Juga, apa perilaku dengan string kosong?
Jo King
@JoKing saya menambahkan program uji. Setiap perubahan karakter yang mungkin dapat terjadi. Itu hanya menunjukkan bahwa setiap posisi dapat dipilih untuk menyisipkan, mengganti, atau menghapus, dan bahwa itu menangani daftar kosong. tio.run/##LYoxDsMgDEVnOAUjCAZgRO0NuIHloUOaRIocy6JDT08dpdt/…
mbomb007
Saya tidak berpikir bahwa tidak ada perubahan yang valid, meskipun saya sudah meminta OP. Pertanyaannya adalahOf course, deleting or replacing a character from an empty string is not a valid change
Jo King
Saya sudah bertanya Buah Esolanging, dan mereka mengatakan bahwa tidak ada perubahan yang valid, tetapi tidak untuk string kosong.
Jo King
1
@ JoKing Harus diperbaiki.
mbomb007
1

Java 10, 370 byte

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));}}

Cobalah online.

Penjelasan:

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

Penjelasan umum:

:

  • String sberisi kode sumber yang tidak diformat.
  • %sdigunakan untuk memasukkan String ini ke dalam dirinya sendiri dengan s.format(...).
  • %c, %1$cdan 34digunakan untuk memformat tanda kutip ganda.
  • ( %%digunakan untuk memformat modulo- %).
  • s.format(s,34,s) menempatkan semuanya bersama-sama.

Di sini program dasar Java quine.

Bagian tantangan:

  • String s; adalah kode sumber yang akan kami modifikasi di tingkat kelas.
  • int r=s.length();r*=Math.random();digunakan untuk memilih indeks acak dari kode sumber dalam kisaran [0, length_of_modified_source_code).
  • char c=127;c*=Math.random();digunakan untuk memilih karakter ASCII acak (termasuk unsintables) dalam rentang unicode [0, 126].
  • c%3digunakan untuk memilih opsi acak 0, 1 atau 2. Opsi 0 akan menambahkan karakter acak sebelum indeks r; opsi 1 akan mengganti karakter pada indeks rdengan karakter acak; dan opsi 2 akan menghapus karakter di indeks r.
Kevin Cruijssen
sumber