엔트로피 퀸!


12

당신의 임무는 다음과 같은 프로그램이나 기능을 작성하는 것입니다.

  • 처음 실행할 때 소스 코드를 출력합니다.
  • 이후의 실행에서는 이전에 출력 한 것을 출력하지만 하나의 임의 문자 변경 (아래 정의)이 있어야합니다. 균일하게 무작위로 변경 될 필요는 없지만, 가능한 모든 변경은 0이 아닌 가능성이 있어야합니다.

    처음 실행 한 후에는 프로그램이 더 이상 퀴네 일 필요 는 없습니다 . 출력이 변경 될 것입니다 (프로그램도 자유롭게 수정할 수 있습니다).

예를 들어, quine이 인 ABCD경우 반복해서 실행하면 다음과 같이 인쇄 될 수 있습니다.

ABCD
A!CD
j!CD
j!CjD

명세서

  • 문자 변경은 다음 중 하나입니다.

    • 임의의 문자 삽입
    • 임의의 문자 삭제 또는
    • 캐릭터를 새로운 랜덤 캐릭터로 교체합니다. 새 캐릭터는 교체 한 캐릭터와 동일 할 수 있으며,이 경우 변경되지 않습니다.

    물론 빈 문자열에서 문자를 삭제하거나 바꾸는 것은 유효한 변경 사항이 아닙니다.

  • 이 태그가 이지만 소스 코드를 읽는 것에 대한 규칙은 적용되지 않습니다.

소스 코드에 사용 된 문자가 포함되어 있으면 문자 세트를 사용할 수 있습니다.


1
문자는 어떤 문자를 나타 냅니까?
Dennis

2
얼마나 자주 작동해야합니까? 당연히 원래의 프로그램보다 길거나 긴 모든 가능한 프로그램이 임의로 해결 될 수는 없습니다.
Martin Ender

1
캐릭터를 어디에서나 끝에 추가 할 수 있습니까?
코너 오브라이언

1
@ ConorO'Brien Anywhere.
Esolanging 과일

1
얼마나 많은 반복 작업이 필요합니까?
dylnan

답변:


7

파이썬 3 , 2882702242121951996194180178168 바이트

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

온라인으로 사용해보십시오!

첫 번째 반복에서 파일 소스 코드를 인쇄 한 후 x를 m이 아닌 새 소스 코드로 설정하는 추가 행을 추가합니다.

설명:

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

hash균일 한 난수를 반환 한다고 가정하면 새로운 문자를 삽입 할 확률은 약 1/6, 기존 문자를 변경하는 확률은 1/6이고 문자를 삭제할 확률은 2/6입니다. 남은 2/6 기회는 무엇입니까? 왜, 그것은 2/6의 시간을 전혀하지 않습니다!

( mbomb007의 답변 에서 채택한 검증 프로그램 있습니다. 온라인으로 사용해보십시오! )


f=__file__첫 번째 단계에서도 도움이 될 것이라고 생각 합니다.
Ørjan Johansen 님

4

파이썬 3 , 205 195 바이트

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)

온라인으로 사용해보십시오!

소스 코드를 읽지 않는 버전을 사용하고 싶었습니다. 생각만큼 나쁜 밝혀졌다, 그리고 30 정도가 뒤에 바이트의 버전 않습니다 . 작동 방식에 대한 설명은 대부분 다른 답변과 동일하지만 소스 코드를 읽을 수 없기 때문에 x가 다르게 초기화됩니다.


4

파이썬 2 , 779801 바이트

소스를 읽을 수 있음을 보여주기 위해 도전 과제를 편집했지만 이미 그 해결책이없는 솔루션을 만들고있었습니다. 그래서 그것이 가능하다는 것을 보여주기 위해 나는 그것을 끝냈습니다. 소스 파일을 읽지 못했습니다 :

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


온라인으로 사용해보십시오! (이것은 소스를 수정하지 않습니다. 작동하려면 소스를 로컬로 실행해야합니다)

변환이 작동 함을 보여주기 위해 여기에 테스트 프로그램이 있습니다 (현재는 항상 100for로 설정되어 있으며 초기 목록 r의 모든 조합 np초기 목록에 대한 결과를 인쇄합니다 ).



설명:

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

첫 번째 줄은 고전적인 헛소리이지만 나중에 나오는 것을 설명하는 데 훨씬 더 오래 걸립니다.

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

임의의 정수를 가져옵니다. L소스 코드의 서수 목록이되지만 처음에는 문자열 대체를 위해 소스의 다른 곳에서 사용되지 않는 정수입니다. 파일을 열어서 새 소스를 작성하십시오. 나중에 실행하면 대신 추가하기 위해 열립니다.

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

첫 번째 및 세 번째 코드 줄을 제거하십시오. 를 교체 4서수의 목록 위.

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

조각으로:

  • if L>5:-첫 실행시이 줄을 건너 뜁니다. 나중에, L목록이 될 것이고, 이것은 실행될 것입니다. exec마지막으로 처음 실행되지 않기 때문에 마지막으로 설명하겠습니다 .

  • n-난수 0-2. 이것은 어떤 수정이 발생하는지 결정합니다 (0 = 삽입, 1 = 교체, 2 = 삭제).

  • p -목록에서 수정이 발생하는 임의의 위치입니다.

  • r -목록에 삽입하거나 바꿀 난수

  • f.write("%03d"*3%(n,p,r))-소스 파일의 끝에 3 개의 랜덤을 추가하십시오. 모든 실행에서, 이것은 발생 된 초기 소스에 대한 모든 변경 사항을 인코딩하는 정수에 추가됩니다.

  • exec'b=[];h=%d...'%1...-난수 ( %1나중에 실행 한 후에 찾음 )를 가져 와서 변경 사항을 목록에 적용하고 인쇄합니다.

  • while~-h:b+=[h%%1000];h/=1000- 1선행 0을 고려하여 지금까지 생성 된 난수 목록을 작성하여 선행 0을 고려하십시오.

  • while 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] -(0 = 삽입, 1 = 교체, 2 = 삭제)

  • print"".join(map(chr,L)) -수정 된 소스를 인쇄하십시오.


이것은 때때로 문자열의 끝에서 존재하지 않는 문자를 삭제합니까? p문자열의 길이가 될 수 있기 때문입니다. 또한 빈 문자열의 동작은 무엇입니까?
조 왕

@JoKing 테스트 프로그램을 추가했습니다. 가능한 모든 문자 변경이 발생할 수 있습니다. 삽입, 바꾸기 또는 삭제를 위해 모든 위치를 선택할 수 있으며 빈 목록을 처리한다는 것을 보여줍니다. tio.run/##LYoxDsMgDEVnOAUjCAZgRO0NuIHloUOaRIocy6JDT08dpdt/…
mbomb007

OP에 요청했지만 변경 사항이 유효하지 않다고 생각합니다. 질문은 말합니다Of course, deleting or replacing a character from an empty string is not a valid change
Jo King

나는 Esolanging Fruit에게 물었고, 그들은 아무런 변화 유효하지 않지만 빈 문자열 아니라고 말합니다 .
조 왕

1
@JoKing 수정해야합니다.
mbomb007

1

자바 10, 370 바이트

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

온라인으로 사용해보십시오.

설명:

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

일반적인 설명 :

part :

  • 문자열 s은 형식화되지 않은 소스 코드를 포함합니다.
  • %s를 사용하여이 문자열을 자체에 입력하는 데 사용됩니다 s.format(...).
  • %c, %1$c그리고 34이중 따옴표를 포맷하는 데 사용됩니다.
  • ( %%모듈로 형식화하는 데 사용됨 %).
  • s.format(s,34,s) 그것을 모두 합치십시오.

여기에 기본적인 Java quine 프로그램이 있습니다.

도전 과제 :

  • String s; 클래스 수준에서 수정할 소스 코드입니다.
  • int r=s.length();r*=Math.random();범위에서 소스 코드의 임의 인덱스를 선택하는 데 사용됩니다 [0, length_of_modified_source_code).
  • char c=127;c*=Math.random();유니 코드 범위에서 임의의 ASCII 문자 (인쇄 불가능한 문자 포함)를 선택하는 데 사용됩니다 [0, 126].
  • c%30, 1 또는 2의 임의 옵션을 선택하는 데 사용됩니다. 옵션 0은 색인 앞에 임의의 문자를 추가합니다 r. 옵션 1은 색인의 문자를 r임의 의 문자로 대체합니다 . 옵션 2는 index의 문자를 제거합니다 r.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.