Quine Entropic!


12

Nhiệm vụ của bạn là viết một chương trình hoặc chức năng:

  • Khi chạy lần đầu tiên, xuất mã nguồn của nó.
  • Trong các lần thực hiện tiếp theo, nó sẽ xuất ra những gì nó xuất ra trước đó, nhưng với một thay đổi ký tự ngẫu nhiên (được xác định bên dưới). Nó không phải là một sự thay đổi ngẫu nhiên thống nhất, nhưng mọi thay đổi có thể sẽ có cơ hội xảy ra khác không.

    Sau lần thực hiện đầu tiên, chương trình của bạn sẽ không nhất thiết phải là một câu hỏi nữa; đầu ra sẽ thay đổi (và chương trình cũng được tự do sửa đổi).

Ví dụ: nếu quine của bạn là ABCD, chạy liên tục thì nó có thể in:

ABCD
A!CD
j!CD
j!CjD

Thông số kỹ thuật

  • Thay đổi nhân vật là:

    • Việc chèn một ký tự ngẫu nhiên,
    • Việc xóa một ký tự ngẫu nhiên, hoặc
    • Một sự thay thế của một nhân vật với một nhân vật ngẫu nhiên mới. Lưu ý rằng ký tự mới được phép giống với ký tự thay thế, trong trường hợp đó sẽ không có thay đổi nào được thực hiện.

    Tất nhiên, xóa hoặc thay thế một ký tự từ một chuỗi trống không phải là một thay đổi hợp lệ.

  • Mặc dù điều này được gắn thẻ , các quy tắc chống đọc mã nguồn của bạn không được áp dụng.

Bạn có thể sử dụng bất kỳ bộ ký tự nào miễn là nó bao gồm các ký tự được sử dụng trong mã nguồn của bạn.


1
Có gì nhân vật nào từng nhân vật tham khảo?
Dennis

2
Làm thế nào thường xuyên này phải làm việc? Rõ ràng nó không thể tùy tiện thường xuyên hoặc nếu không mọi chương trình có thể dài hơn hoặc dài hơn chương trình ban đầu phải là một giải pháp cho thách thức.
Martin Ender

1
Nhân vật có thể được thêm vào bất cứ nơi nào, hoặc chỉ ở cuối?
Conor O'Brien

1
@ ConorO'Brien ở mọi nơi.
Trái cây Esolanging

1
Có bao nhiêu lần lặp để làm việc?
dyl Nam

Câu trả lời:


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

Hãy thử trực tuyến!

Sau khi in mã nguồn tệp trong lần lặp đầu tiên, chúng tôi nối thêm một dòng bổ sung để đặt x thành mã nguồn mới, thay vì m.

Giải trình:

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

Giả sử hashtrả về một số ngẫu nhiên thống nhất, có khoảng 1/6 cơ hội chèn một ký tự mới, 1/6 cơ hội thay đổi một ký tự hiện có và 2/6 cơ hội xóa một ký tự. 2/6 cơ hội còn lại bạn yêu cầu là gì? Tại sao, nó không làm gì cả 2/6 thời gian!

(Đây là một chương trình xác nhận được điều chỉnh từ câu trả lời của mbomb007 . Hãy thử trực tuyến! )


Tôi nghĩ rằng f=__file__sẽ giúp trong bước đầu tiên quá.
Ø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)

Hãy thử trực tuyến!

Muốn thử một phiên bản không đọc mã nguồn. Hóa ra không phải là một xấu như tôi nghĩ, và nó chỉ có 30 hoặc lâu hơn byte đằng sau những phiên bản đó không . Giải thích cho cách thức hoạt động của nó hầu hết giống như câu trả lời khác, nhưng nó khởi tạo x khác nhau vì nó không thể đọc được mã nguồn.


4

Python 2 , 779 801 byte

Mặc dù thử thách đã được chỉnh sửa để cho thấy rằng việc đọc nguồn của bạn được cho phép, tôi đã tạo ra giải pháp của mình mà không cần điều đó. Vì vậy, để cho thấy rằng nó có thể, tôi đã hoàn thành nó. Không đọc tệp nguồn:

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

Hãy thử trực tuyến! (Lưu ý rằng điều này sẽ không sửa đổi nguồn. Bạn phải chạy nó cục bộ để nó hoạt động)

Để chứng minh rằng các biến đổi làm việc, đây là một chương trình thử nghiệm (hiện được thiết lập để luôn luôn chọn 100cho r, và nó in kết quả cho mỗi sự kết hợp của npcho danh sách ban đầu.)



Giải trình:

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

Dòng đầu tiên là quine cổ điển của bạn, nhưng lâu hơn nhiều để tính đến những gì đến sau.

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

Nhập cho số nguyên ngẫu nhiên. Lsẽ trở thành danh sách thứ tự của mã nguồn, nhưng ban đầu nó là một số nguyên không được sử dụng ở bất kỳ nơi nào khác trong nguồn để cho phép thay thế chuỗi. Mở tệp để viết nguồn mới. Trong các lần chạy sau, nó sẽ mở để nối thêm.

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

Loại bỏ các dòng mã đầu tiên và thứ ba. Thay thế 4ở trên với danh sách các chức.

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

Trong phần:

  • if L>5:- Bỏ qua dòng này trong lần thực hiện đầu tiên. Sau đó, Lsẽ là một danh sách, và điều này sẽ chạy. Tôi sẽ giải thích execlần cuối, vì nó không chạy lần đầu tiên.

  • n- Một số ngẫu nhiên 0-2. Điều này xác định sửa đổi nào xảy ra (0 = insert, 1 = thay thế, 2 = xóa).

  • p - Một vị trí ngẫu nhiên trong danh sách mà sửa đổi sẽ xảy ra tại.

  • r - Một số ngẫu nhiên để chèn hoặc thay thế trong danh sách

  • f.write("%03d"*3%(n,p,r))- Nối 3 randoms vào cuối tệp nguồn. Mỗi lần chạy, điều này sẽ được thêm vào một số nguyên mã hóa tất cả các thay đổi đối với nguồn ban đầu đã xảy ra.

  • exec'b=[];h=%d...'%1...- Nhận các số ngẫu nhiên (được tìm thấy sau các %1lần chạy sau), áp dụng các thay đổi cho danh sách và in.

  • while~-h:b+=[h%%1000];h/=1000- Xây dựng một danh sách các randoms được tạo ra cho đến nay, chiếm vị trí hàng đầu 1, trong đó ngăn ngừa các vấn đề với các số 0 đứng đầu.

  • while b:r,p,n=b[-3:];b=b[:-3] - Chỉ định các randoms cho lần lặp này.

  • L=[L[:p]+L[p+1:],L[:p]+[r]+L[p+n:]][n<2if L else 1] - (0 = chèn, 1 = thay thế, 2 = xóa)

  • print"".join(map(chr,L)) - In nguồn đã sửa đổi.


Điều này đôi khi xóa một ký tự không tồn tại từ cuối chuỗi? Vì pcó thể là chiều dài của chuỗi. Ngoài ra, những gì hành vi với một chuỗi trống?
Jo King

@JoKing Tôi đã thêm một chương trình thử nghiệm. Mỗi thay đổi nhân vật có thể xảy ra. Nó chỉ cho thấy rằng mọi vị trí có thể được chọn để chèn, thay thế hoặc xóa và nó xử lý một danh sách trống. tio.run/##LYoxDsMgDEVnOAUjCAZgRO0NuIHloUOaRIocy6JDT08dpdt/...
mbomb007

Tôi không nghĩ rằng không có thay đổi nào là hợp lệ, mặc dù tôi đã hỏi OP. Câu hỏi có nóiOf course, deleting or replacing a character from an empty string is not a valid change
Jo King

Tôi đã hỏi Esolanging Fruit và họ nói rằng không có thay đổi nào hợp lệ, nhưng không phải là một chuỗi trống.
Jo King

1
@JoKing Nên sửa.
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));}}

Hãy thử trực tuyến.

Giải trình:

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

Giải thích chung:

-part:

  • Chuỗi schứa mã nguồn chưa được định dạng.
  • %sđược sử dụng để nhập Chuỗi này vào chính nó với s.format(...).
  • %c, %1$c34được sử dụng để định dạng dấu nháy kép.
  • ( %%được sử dụng để định dạng modulo- %).
  • s.format(s,34,s) đặt tất cả lại với nhau

Đây là một chương trình quine Java cơ bản.

Phần thử thách:

  • String s; là mã nguồn chúng tôi sẽ sửa đổi ở cấp độ lớp.
  • int r=s.length();r*=Math.random(); được sử dụng để chọn một chỉ mục ngẫu nhiên của mã nguồn trong phạm vi [0, length_of_modified_source_code) .
  • char c=127;c*=Math.random();được sử dụng để chọn một ký tự ASCII ngẫu nhiên (bao gồm cả không thể in được) trong phạm vi unicode [0, 126].
  • c%3được sử dụng để chọn tùy chọn ngẫu nhiên là 0, 1 hoặc 2. Tùy chọn 0 sẽ thêm ký tự ngẫu nhiên trước chỉ mục r; tùy chọn 1 sẽ thay thế ký tự tại chỉ mục rbằng ký tự ngẫu nhiên; và tùy chọn 2 sẽ loại bỏ ký tự tại chỉ mục r.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.