상호 부정적인 Quines


22

이것은 당신의 코드를 부정적 으로 인쇄 하고 골프를 서로 대화 하는 것에서 영감을 받았습니다 .


다음 제한 사항을 충족 하는 직사각형 의 문자를 고려하십시오 .

  1. 인쇄 가능한 ASCII 문자 로만 구성
  2. 1보다 큰 치수
  3. 각 행과 각 열에는 하나 이상의 공백이 포함됩니다.
  4. 각 행과 각 열에는 공백이 아닌 문자가 하나 이상 포함되어 있습니다.

예를 들어, 다음은 유효한 6x4 사각형입니다.

%n 2e 
1  g 3
 &* __
 3  

이 사각형 의 음수 는 모든 공백이 공백이 아닌 문자로 대체되고 공백이 아닌 모든 문자가 공백으로 대체 된 동일한 차원의 사각형으로 정의됩니다. 위 사각형의 음수는 다음과 같습니다.

  f  ^
 33 > 
9  $  
^ }|Q'

공백을 인쇄 할 수있는 공백이 아닌 인쇄 가능한 ASCII 문자를 사용할 수 있습니다.

태스크

당신의 임무는 사각형 소스 코드로 프로그램을 작성하는 것입니다. 네거티브 출력은 원본과 동일한 언어로 유효한 프로그램이어야하며 원본의 소스를 출력해야합니다.

선택 사항 인 출력의 끝에 단일 후행 줄 바꿈을 제외하고 후행 공백을 추가하거나 제거 할 수 없습니다.

어느 프로그램도 소스 코드를 읽을 수 없습니다. REPL 환경도 가정 할 수 없습니다.

채점

점수는 코드 크기의 곱입니다 (예 : 소스 코드가 12 x 25 사각형 인 경우 점수는 12 * 15 = 180). 또한 주석에 사용 된 각 문자에 대해 점수가 2 씩 증가 /* .. */합니다 (코드에서 한 번 사용 하고 코드가 10 x 10 사각형 인 경우 점수는 10 * 10 + 8 * 2 = 116입니다).

가장 낮은 점수가 이깁니다.

동점이있는 경우 프로그램에서 가장 적은 수의 공간 (원본 또는 음수 중 더 적은 수의 공간)을 가진 제출물이 이깁니다.

여전히 동점이 남아 있다면, 빠른 답변이 이길 것입니다.

원래와 네거티브를 함께 결합하여 정상적인 퀘인을 생성하면 -52 % 의 보너스가 있습니다 . 예를 들면 다음과 같습니다.

Original   Negative   Combined
 A A       B B        BABA
A A         B B       ABAB

@Optimizer 이것이 보너스를 필수로하지 않은 이유입니다.
es1024

1
나는 단지 부정적인 상호 퀘인 부분에 대해 이야기하고 있습니다;)
Optimizer

@ MartinBüttner 아, 내 나쁜. 나는 이상한 말로 생각하고 있었다.
Optimizer

1
누구든지 c에서 이것을 할 수 있습니까? 누구든지 먼저 +1합니다!
MegaTom

답변:


15

CJam, ( 51 49 47 46 45 42 x 2) * 48 % = 40.32

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 
                                         R

위 코드를 실행하면 다음과 같은 결과가 출력됩니다.

                                         R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 

원본 소스를 다시 인쇄합니다.

소스와 출력은 단순히 스왑 된 라인입니다.

이제 마법이 온다.

소스와 출력을 겹치면 다음 코드로 출력됩니다.

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R

완벽한 퀴네입니다!

여기에서 온라인으로 사용해보십시오


작동 원리

모든 인쇄 논리는 첫 번째 줄 자체에 있으며 나중에 설명 할 세 가지 경우를 모두 처리합니다.

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~
{                                     }_~   "Copy this code block and execute the copy";
 ]                                          "Wrap everything before it in array";
  )                                         "Pop the last element out of it";
   "_~"+                                    "Append string '_~' to the copied code block";
        S41*                                "Create a string of 41 spaces";
            'R+                             "Append character R to it";
               @,                           "Rotate the array to top and get its length";
                 [{   }{   }{     }]=~      "Get the corresponding element from this"
                                            "array and execute it";

위의 마지막 줄에있는 배열은 세 경우 모두에 해당하는 코드 블록이있는 배열입니다.

사례 1

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 
                                         R

이 경우, 블록이 실행될 때 남아있는 스택의 길이는 0이었고, 블록 자체의 사본 만 가지고 있었으며, 처음에는 위의 세 번째 단계에서 튀어 나왔습니다. 따라서 0마지막 배열 에서 인덱스를 가져 와서 실행하십시오.

 {N@S}          "Note that at this point, the stack is something like:"
                "[[<code block that was copied> '_ '~ ] <41 spaces and R string>]";
  N             "Add newline to stack";
   @            "Rotate the code block to top of stack";
    S           "Put a trailing space which negates the original R";

이 경우 출력을 인쇄하는 한 두 번째 줄은 작동하지 않습니다.

사례 2

                                         R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 

이 경우 스택에는 이미 빈 문자열이 포함되어 있으므로 복사 된 코드 블록이 실행될 때 빈 문자열과 코드 블록 자체라는 두 가지 요소가있었습니다. 따라서 1마지막 배열 에서 인덱스를 가져 와서 실행하십시오.

{SN@}            "Note at this point, the stack is same as in case 1";
 SN              "Push space and newline to stack";
   @             "Rotate last three elements to bring the 41 spaces and R string to top";

사례 3

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R

이 경우 스택에는 6 개의 요소가 있습니다. 마지막 코드 블록을 띄운 후 남은 배열 길이는 5 5입니다. 배열 에서 인덱스를 꺼내서 실행합니다. ( 3요소 배열 에서 index 5는 index입니다 5%3 = 2)

{W=N]_}          "Note at this point, the stack is same as in case 1";
 W=              "Take the last character out of the 41 spaces and R string, i.e. R";
   N]            "Add a new line to stack and wrap the stack in an array";
     _           "Copy the array to get back the source of Case 3 itself";

27

파이썬, 97x2 + 2 = 196

시작하기에 좋은 해결책은 아니지만 적어도 효과가 있습니다 (제 생각에는).

c='o=1-%d;print("%%97s\\n%%97s"%%("#","c=%%r;exec(c%%%%%%d)\\40"%%(c,o),"#")[o:][:2])';exec(c%1) 
                                                                                                #

산출:

                                                                                                #
c='o=1-%d;print("%%97s\\n%%97s"%%("#","c=%%r;exec(c%%%%%%d)\\40"%%(c,o),"#")[o:][:2])';exec(c%0) 

8
1 만 제출은 지금까지 실제 언어 사용을 위해
WinnieNicklaus

보너스와 너무 멀지 않은 것 같습니다.
mbomb007

23

CJam, ( 58 56 54 48 46 x 2) * 48 % = 44.16

{`"_~"+{_,94\m2/S*a_+\*                       
                       N/23f/Wf%N*}_`'"#)!*}_~

인쇄

                       {`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~                       

각 줄의 공백이 아닌 문자는 두 개의 상호 퀴즈 사이에서 동일하게 유지됩니다.

그러나 지금 정말 달콤한 부분 :

{`"_~"+{_,94\m2/S*a_+\*{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~N/23f/Wf%N*}_`'"#)!*}_~

quine입니다! :)

여기에서 테스트하십시오.

작동 원리

CJam에서 일반적으로 퀴닝의 기본 사항을 설명하기 때문에 다른 제출물에 대한 설명을 먼저 읽는 것이 좋습니다.

이것은 조금 까다 롭습니다. 다른 경우와 같이 상호 quine의 경우 각 줄 앞뒤에 공백을 추가하고 0을 2로 바꿔서 결과 프로그램이 공백을 반대쪽 끝에 놓아 블록의 문자열 표현을 수정합니다.

공백은 상호 퀴즈에 전혀 영향을 미치지 않습니다. 첫 번째는 실제로 사용되지 않는 블록에 있으며 두 번째는 전체 코드 주위에 있습니다.

두 가지를 결합 할 때 정기적으로 퀴인을 얻으려면 모든 수정을 피하는 방법을 찾아야합니다. 공백과 코드의 구조는 둘을 결합함으로써 한 퀴니 전체를 다른 퀴니에 삽입한다는 것을 의미합니다. 따라서 전체 수정 코드를 블록에 넣으면 실제 내용에 따라 해당 블록을 실행할 수 있습니다.

이제이 블록이 있습니다 ... 상호 퀴인에는 실제로 실행하려는 코드 만 포함됩니다. 결합 된 quine의 경우, 임의의 위치에 임의의 의미로 전체 quine을 다시 포함하지만 ... 블록이기 때문에 자동으로 실행되지 않습니다. 따라서 해당 블록의 내용을 기반으로 문자열을 수정할지 여부를 결정할 수 있습니다. 그게 다야 _`'"#)!. 블록을 복제하고 문자열로 변환하고 문자를 검색합니다 "(상호 quine에서는 블록 외부 에만 나타남 ) -1. 문자를 찾을 수 없으면 검색이 반환 되고 그렇지 않으면 양의 정수가 반환 됩니다. 결과가 증가합니다. 논리적으로 부정합니다. 따라서 a "가 발견되면 0그렇지 않으면 결과가됩니다 1. 이제 우리는 단지*결과가 1이고 전혀 그렇지 않은 경우 블록을 한 번 실행합니다.

마지막으로 다음과 같이 수정 코드가 작동합니다.

_,94\m2/S*a_+\*N/23f/Wf%N*
_,                         "Duplicate the quine string and get its length.";
  94\m                     "Subtract from 94.";
      2/                   "Divide by two.";
        S*                 "Create a string with that many spaces. This will be
                            an empty string for the first mutual quine, and contain
                            23 spaces for the second mutual quine.";
          a_+              "Create an array that contains this string twice.";
             \*            "Join the two copies together with the quine string.";
               N/          "Split into lines.";
                 23f/      "Split each line into halves (23 bytes each).";
                     Wf%   "Reverse the two halves of each line.";
                        N* "Join with a newline.";

현상금 청구, (12 x 10) * 48 % = 57.6

이 코드는 약간의 수정으로 더 많은 줄로 쉽게 나눌 수 있습니다. 우리는 2 개의 문자를 추가하여 48 행을 얻습니다. 그러면 8로 편리하게 나눌 수 있습니다. 그래서 6 줄의 코드와 6 칸의 8 줄을 갖습니다. 이를 위해 몇 개의 숫자를 변경하고 연산자를 두 개로 재정렬해야하므로 두 줄로 나뉘 지 않습니다. 그것은 우리에게 12 x 8 크기의 작업 버전을 제공합니다 ... 그래서 우리는 아무것도하지 않는 두 줄을 추가합니다 (1 푸시, 1 팝, 1 푸시, 1 팝 ...). 12 x 10 :

{`"_~"      
      +{129X
$,m2/S      
      *a_+\*
N/6f/1      
      ;1;1;1
;1;1;1      
      ;Wf%N*
}_`'"#      
      )!*}_~

이전과 같이

      {`"_~"
+{129X      
      $,m2/S
*a_+\*      
      N/6f/1
;1;1;1      
      ;1;1;1
;Wf%N*      
      }_`'"#
)!*}_~      

(측면 참고 : 중간 라인에서 왼쪽과 오른쪽을 교대로 유지할 필요는 없으며 첫 번째와 마지막 라인의 위치 만 중요합니다. 다른 모든 라인에 대해 왼쪽과 오른쪽을 임의로 선택할 수 있습니다.)

그리고 순수한 우연의 일치를 통해 전체 quine도 여전히 작동합니다.

{`"_~"{`"_~"
+{129X+{129X
$,m2/S$,m2/S
*a_+\**a_+\*
N/6f/1N/6f/1
;1;1;1;1;1;1
;1;1;1;1;1;1
;Wf%N*;Wf%N*
}_`'"#}_`'"#      
)!*}_~)!*}_~

(내부 코드를 실행하지 않는 부분은 다른 퀴인과 이상하게 산재 해 있지만 여전히 잘 작동하기 때문에 우연의 일치라고 말합니다.)

1;, 바운티 요구 사항을 충족시키기 위해 원본 제출에 44 줄을 추가 할 수 있었지만 12 x 10훨씬 깔끔해 보입니다. ;)

편집 : 하하, "순수한 우연의 일치"라고 말했을 때 나는 더 이상 주목할 수 없었습니다. 마지막 퀴니가 실제로 어떻게 작동하는지 살펴 보았습니다. 3 개의 중첩 된 블록이 있습니다 (실제로 4 개이지만 가장 안쪽 블록은 관련이 없음). 이 3 개의 블록 중 가장 안쪽 부분의 유일한 중요한 부분은 블록을 포함 "한다는 것 '"입니다. quine의 기본 구조는 다음과 같습니다.

{`"_~"{`"_~"+{___'"___}_`'"#)!*}_~)!*}_~

그것을 해보자.

{`"_~"                               }_~ "The standard CJam quine.";
      {`"_~"+                  }_~       "Another CJam quine. Provided it doesn't do 
                                          anything in the rest of that block, this 
                                          will leave this inner block as a string on 
                                          the stack.";
                                  )      "Slice the last character off the string.";
                                   !     "Negate... this yields 0.";
                                    *    "Repeat the string zero times.";

그래서 이것은 실제로 재미있는 마술을하지만 내부 블록이 스택에 단일 문자열을 남기기 때문에 )!*빈 문자열로 바꿉니다. 유일한 조건은 내부 블록의 내용 +이 스택에 다른 작업을 수행하지 않는다는 것입니다.

             {___'"___}                  "Push a block which happens to contain 
                                          quotes.";
                       _`'"#)!*          "This is from the original code and just 
                                          removes the block if it does contain 
                                          quotes.";

4
TLDR; upvote;)
최적화 도구

Y/2결합 된 퀴네에 포함되어 있지 않아야 합니까?
schnaader

"순수한 우연의 일치"nah;)
Timtech

@Timtech 내 편집 내용을 참조하십시오. 순수한 우연의 일치는 과소 평가가 아니었다. ^^
Martin Ender

10

CJam, 42 37 33 x 2 = 66

{`As_W%er"_~"+S 33*F'Lt1{\}*N\}_~
               L                 

인쇄

               L                 
{`As_W%er"_~"+S 33*F'Lt0{\}*N\}_~

(라인이 1바뀌고가로 바뀝니다 0.)

여기에서 테스트하십시오.

작동 원리

먼저 기본적인 CJam quine을 이해해야합니다.

{"_~"}_~

중괄호는 함수와 같이 즉시 실행되지 않는 코드 블록을 정의합니다. 실행되지 않은 블록이 스택에 남아 있으면 소스 코드 (중괄호 포함)가 인쇄됩니다. _블록을 복제하고 ~두 번째 사본을 실행합니다. 블록 자체는 단순히을 포함하는 문자열을 푸시합니다 _~. 따라서이 코드는 스택을 다음 상태로 둡니다.

Stack: [{"_~"} "_~"]

프로그램 종료시 블록과 문자열이 단순히 연속으로 인쇄되므로이 작업은 문제가됩니다.

이것의 장점은 우리가 블록에서 원하는 모든 것을 할 수 있다는 것입니다. 각 코드 조각이 자동으로 블록 내용에 인쇄되기 때문에 퀴네로 남아 있습니다. 또한 블록 표현을 사용하여 블록을 수정할 수도 있습니다 `(중괄호가있는 블록의 문자열).

이제이 솔루션을 살펴 보겠습니다. 상호 퀴인의 일부에는 _~, 및으로 퀴인 유사 블록이 포함되어 있습니다 L. 는 L출력에 기여하지 않는 스택 위에 빈 문자열을 푸시합니다. 블록은 다음과 같습니다.

`                             "Convert block to its string representation.";
 As                           "Push 10 and convert to string.";
   _W%                        "Duplicate and reverse, to get another string 01.";
      er                      "Swap 0s and 1s in the block string.";
        "_~"+                 "Append _~.";
             S 33*            "Push a string with 33 spaces.";
                  F'Lt        "Set the character at index 15 to L.";
                      1{ }*   "Repeat this block once.";
                        \     "Swap the code string and the space string.";
                           N\ "Push a newline and move it between the two lines.";

따라서 이것은 quine 부분을 수행하지만 1을 0으로 바꾸고 L위의 코드에 공백이있는 다른 행을 앞에 추가 합니다. 그 두 줄의 순서는 내부 스와핑에 의해 결정됩니다 { }*. 그리고 상호 퀴인의 외부 부분 0앞에는을 대치 1하여이 스왑을 실행하지 않으므로 원래 순서를 다시 생성합니다.


5

CJam, 27 × 2 = 54

{ ` " _ ~ " + N - ) 2 * ' '
 > @ t s G B + / N * } _ ~ 

산출:

 { ` " _ ~ " + N - ) 2 * ' 
' > @ t s G B + / N * } _ ~

'A'B>문자 A와 B를 비교합니다. ' '\n >32> 10이므로 1을 ' \n' >반환하고 두 공백이 같으므로 0을 반환합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.