견적 안전 Quines


17

당신의 작업은 간단합니다 : 소스 코드를 입력 및 출력하지 않거나 리턴하는 프로그램 (또는 함수)을 작성하십시오. 캐치가 프로그램이 랩핑 될 때 "quotes"(유니 코드 문자 34) 다시 소스 코드를 출력해야한다는 것입니다.

quines에 대한 표준 규칙이 적용됩니다. 이것은 이므로 가장 짧은 프로그램 (바이트)이 이깁니다.


8
@ATaco는 창의적으로 생각합니다. 따옴표 안의 코드는 일반적으로 실행되지 않지만 전체 프로그램이 따옴표로 묶여 있으면 해당 섹션 실행됩니다.
Pavel

1
흠, 좋은 지적이다.
ATaco

이는 BF와 함께 다음을 지원하는 구현에서 작동 할 수 있습니다 !.
Esolanging Fruit

1
사용해야 "합니까? 일부 언어는 2 ~ 3 개의 따옴표 문자를 지원합니다.
Neil

1
@ tkellehe Meta : 적절한 quine으로 간주되는 것은 무엇입니까? 귀하의 1 바이트 퀴인을 이해하는 한, 그것은 가장 높은 투표 게시물에 공식화 된 코드 / 데이터 요구 사항을 위반합니다.
Laikoni

답변:


4

누델 , 9 7 바이트

이 버전은 다른 버전과 동일한 방식으로 작동합니다. Noodel 이 코드 블록을 한 번 실행하는 방법을 잊어 버렸고 언어를 만들었습니다 ...

Ḷ1ḥ-Ð1ḥ@€

ḷḥ-Ðḥ@ḅ

시도 해봐:)


작동 원리

ḷḥ-Ðḥ@ḅ # Single statement that builds itself as a string.
ḷ       # Loop the following block of code unconditionally.
 ḥ-     # Push the string literal of the token preceding this one which pushes "ḷ" onto the stack.
   Ð    # Push the stack as an array to stdout (since is an array it is done by reference).
    ḥ@  # Push the string literal for this block of code which pushes "ḥ-Ðḥ@ḅ" onto the stack.
      ḅ # Break out of the given loop. (The stack is now ["ḷ", "ḥ-Ðḥ@ḅ"]).

        # The top of the stack is popped off and displayed which modifies the array to produce {["ḷ"], "ḥ-Ðḥ@ḅ"} in stdout.

견적 안전

Noodel 에는 내가 인쇄용 이라고 부르는 문자 세트가 "있기 때문에 프로그램 전후 에 문자를 배치하십시오 . 이것들은 스스로 배치 할 때 즉시 문자열 리터럴로 구문 분석되어 화면에 쉽게 인쇄 할 수 있습니다. 따라서 대부분의 언어와 달리 Noodel 은 인쇄에서 직접 문자열 리터럴 (공백 및 줄 바꿈 제외)로 사용할 수있는 것으로 간주 되는 일반 ASCII 세트를 인용하여 코드를 인용하면 문자열을 푸시하는 것으로 간주됩니다.

"ḷḥ-Ðḥ@ḅ"

"         # Pushes on the string literal "\"" onto the stack.

 ḷḥ-Ðḥ@ḅ  # Same execution as before, simply builds the Quine for this loop.
 ḷ        # Loop the following block of code unconditionally.
  ḥ-      # Push the string literal of the token preceding this one which pushes "ḷ" onto the stack.
    Ð     # Push the stack as an array to stdout (since is an array it is done by reference).
     ḥ@   # Push the string literal for this block of code which pushes "ḥ-Ðḥ@ḅ" onto the stack.
       ḅ  # Break out of the given loop. (The stack is now ["\"", "ḷ", "ḥ-Ðḥ@ḅ"]).

        " # Pushes on the string literal "\"" onto the stack.

          # The top of the stack is popped off and displayed which modifies the array to produce {["\"", "ḷ", "ḥ-Ðḥ@ḅ"], "\""} in stdout.

"시도 해봐:)"


짧은 발췌

<div id="noodel" code='ḷḥ-Ðḥ@ḅ' input="" cols="10" rows="1"></div>
<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>


<div id="noodel" code='"ḷḥ-Ðḥ@ḅ"' input="" cols="10" rows="1"></div>
<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>


사용 e이 유효 하다고 생각하지 않습니다 . 질문은 바이트 34로 인코딩 된 문자를 요구하지 않고 유니 코드 문자 34를 요구합니다. 어떤 인코딩을 사용하든 다음 중 하나만 있습니다."
Dennis

@Dennis, 나는 당신이 말하는 것이 유니 코드 문자 34에 대한 참조가 모든 사람들이 동일한 것을 사용하도록 보장하는 것이라고 추측합니다. " 있습니까? (죄송합니다, 당신이 무슨 말을하는지 이해하려고 노력하고 있습니다.) 또한, 사용하는 것과 관련하여 답변에서 모든 텍스트를 제거해야 e합니까?
tkellehe

1
예, 수천 개의 인코딩이 있지만 유니 코드 문자 집합은 하나만 있습니다. 이후"작동 토론을 제거하고 간단히을 사용 "합니다.
Dennis

11

파이썬 2 3 181 152 130 124 122 바이트

""" """>" "or exec("oct=0");p='"""" """>" "or exec("oct=0");p=%r;a=oct==0;print(p[a:~a]%%p)#".';a=oct==0;print(p[a:~a]%p)#

온라인으로 사용해보십시오! TIO에는 퀴의 유효성을 자동으로 테스트하는 머리글과 바닥 글이 있습니다. quine을 실행하기 위해 그것들을 지울 수 있습니다.

이 코드는 파이썬에서 삼중 인용 문자열을 사용하여 작동합니다. """ """같은지 ' '"""" """같다 '" '.

코드는 exec표현식을 사용하여 변수를 설정하기 위해 코드로 데이터를 실행하는 "비-퀴니 (non-quiney)"방식 에는 사용하지 않습니다. 또한 exec데이터에 올바르게 인코딩됩니다.

첫 번째 문장은 문자열과 인용 부호가 붙은 문자열을 비교하고 그에 따라 " "변수를 설정합니다 oct. (변수는 짧게 내장되었을 수 있습니다.)

그런 다음 나머지 코드는 %r문자열 형식을 사용하여 기존 파이썬 퀴인을 구현하며 oct변경되지 않은 경우 추가 따옴표를 제거하는 추가 코드가 있습니다.

"cheaty"를 사용하는 대체 버전 exec은 덜 반복되는 코드와 함께 126 바이트로 제공됩니다.

""" """>" "and exec("oct=0");s='"""" """>" "and exec("oct=0");s=%r;p=%r;exec(p)#".';p='a=oct!=0;print(s[a:~a]%(s,p))';exec(p)#

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


7

표준 ML , 182176 바이트

";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))

인용 되지 않은 버전 : 코딩 그라운드에서 사용해보십시오.
인용 버전 : 코딩 그라운드에서 사용해보십시오.

출력은 다음과 같습니다.

> val it = "{some string}" : string
> val it = "{some string}" : string
{output to stdout}> val it = fn : string -> unit

코드는 선언에 의한 선언으로 해석되고 (각각 ;선언이 종료 됨) 각 선언의 값과 유형을 보여줍니다.


배경

SML에는 다음과 같은 형식이 있습니다 <code>"<code in quotes>".

str(chr 34);(fn x=>print(x^it^x^it))"str(chr 34);(fn x=>print(x^it^x^it))" 

그리고 하나의 형태 "<code in quotes>"<code>:

";str(chr 34)^it;print(it^it)";str(chr 34)^it;print(it^it)

둘 다 사실에 의존 <code> -part에 따옴표가 포함되어 있지 않기 때문에 이스케이프 할 필요없이 인용 할 수 있으며 "quine을 출력하는 데 필요한 값은 str(chr 34)입니다.

또한 암시 적 식별자에 크게 의존합니다. it 선언에 명시 적 식별자가 제공되지 않을 때 사용되는 .

제 quine에서의 str(chr 34);귀속 it함유 문자열 ", fn x=>익명의 기능이 하나 개의 인자를 복용 시작 x후, 연접을 x^it^x^it결과 스트링을 출력한다. 이 익명 함수는 프로그램 코드가 포함 된 문자열에 직접 적용되므로 연결x^it^x^it 생성 <code>"<code>"됩니다.

두 번째 quine ";str(chr 34)^it;print(it^it)";은에 바인딩 된 문자열로 프로그램 코드로 시작 합니다 it. 그런 다음 str(chr 34)^it;따옴표를 문자열의 시작 부분에 연결하고 명시적인 식별자가 주어지지 않으면 결과 문자열 "<code>이에 바인딩됩니다 it. 마지막으로 print(it^it)문자열 자체와 연결하여 "<code>"<code>인쇄합니다.


설명

편집 : 더 이상 108 바이트 버전으로 업데이트되지 않지만이 설명을 읽은 후에도 이해할 수 있습니다.

따옴표로 안전한 quine은 위의 두 가지 접근 방식을 결합하며 그 자체는 형식 "<code>"<code>입니다. 이것을 다시 따옴표로 묶으면 yields ""<code>"<code>"이므로 빈 문자열을 얻은 다음 다른 형식의 quine을 얻습니다.

즉, 프로그램은 "<code>identifier 형식 으로 자체 소스를 제공 it받거나 it단지 "자체 소스 <code>를 인수로 제공하므로 이러한 인수를 처리하는 함수 여야합니다.

(if size it>1then(print(it^it);fn _=>())else fn x=>print(it^it^x^it^x^it))

우리가이 경우에 식별하기 위해, 우리는의 크기가 있는지 여부를 확인 it후 1보다 큰 경우에는없는 it것입니다 "그리고 우리는 두 번째 경우에 너무 elsepart의 반환 익명 함수 fn x=>print(it^it^x^it^x^it)의 문자열로 소스 뒤에 있기 때문에 다음이라고합니다 . it^it^프로그램 시작시 빈 문자열에 필요한 행간 을 주목하십시오 .

경우 size it우리는에 1보다 큰 thenpart의 바로 수행 print(it^it), 오른쪽? SML이 강력하게 형식화되었다는 것을 말하지 않았기 때문에 조건부 if <cond> then <exp_1> else <exp_2>에는 항상 동일한 유형이 있어야하며 이는 표현식 <exp_1>과 유형이 같아야 함을 의미합니다 <exp_2>. 우리는 이미 그 else부분 의 유형을 알고 있습니다 : 문자열을 취해서 호출하는 익명 함수 print는 type string -> <return type of print>print가지고, type string -> unit( 다른 언어 unit와 비슷합니다 void)을 가지므로 결과 타입은 다시 string -> unit입니다.

따라서 then부분 print(it^it)이 type unit인 경우 유형 불일치 오류가 발생합니다. 그럼 fn _=>print(it^it)어때요? ( _그 자체로이 익명 함수 타입했다 사용하지 않는 인자에 대한 와일드 카드이다) 그래서 강제 우리의 조건과 관련하여, 임의의 유형의 약자를 이 작동 할 유형입니다. (type 변수 는 type으로 인스턴스화됩니다 .) 그러나이 경우 익명 함수가 호출되지 않으므로 아무것도 인쇄하지 않습니다! -part에 들어가면 전체 코드는'a -> unit'astring -> unit'astringthen"<code>"<code> -이므로 <code>-part는 함수로 평가되지만 그 뒤에 아무것도 나오지 않으므로 호출되지 않습니다.

대신 우리는 양식이있는 sequentialisation 사용 하는 임의의 유형과 유형이있을 수 있습니다 전체 sequentialisation의 유형을 제공합니다. 기능적인 관점에서 to 의 값 은 단순히 무시되지만 SML은 명령형 구문도 지원하므로 표현식에 부작용이있을 수 있습니다. 즉, 우리 는 -part 로 간주하여 먼저 인쇄 한 다음 올바른 유형 의 함수를 반환합니다 .(<exp_1>; ...; <exp_n>)<exp_1><exp_n-1><exp_n><exp_1><exp_n-1>(print(it^it);print)thenprint


7

V , 27 , 23 바이트

éPñi"éP241"qpá"lxx|xÿ

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

여기에는 인쇄 할 수없는 문자가 포함되어 있으므로 읽을 수있는 버전은 다음과 같습니다.

éPñi"éP<C-v>241<esc>"qpá"lxx|xÿ

그리고 여기 hexdump가 있습니다 :

00000000: e950 f169 22e9 5016 3234 311b 2271 70e1  .P.i".P.241."qp.
00000010: 226c 7878 7c78 ff                        "lxx|x.

따라서 가장 먼저해야 할 일은 첫 번째 문자가 따옴표인지 확인하는 것입니다. éP'P'문자를 삽입하지만 "éPNOOP입니다. 그런 다음 표준 확장 가능 퀴에서 약간 수정합니다.

ñi<C-v>241<esc>"qpÿ

그래도 약간 다르게 할 것입니다. 먼저 시작 "éP"텍스트를 삽입해야합니다. 그래서 우리는

ñ                        " Start recording into register 'q'
 i                       " Enter insert mode
  "éP<C-v>241<esc>       " Enter the following text: '"éPñ'
                  "qp    " Paste the text in register 'q'
                     á"  " Append a '"'

여기에서 분기가 발생합니다. 현재 버퍼에있는 텍스트는

"éPñi"éP<C-v>241<esc>"qpá"P
Cursor is here ----------^

우리가 따옴표로 묶지 않으면이 경우 'P'는 삽입되지 않았으며 버퍼는 다음과 같습니다.

"éPñi"éP<C-v>241<esc>"qpá"
Cursor is here ----------^

우리는 여전히 기록하고 있기 때문에 여기서 원하는 것을 할 수 있으며, "qp일어날 때 버퍼에 추가됩니다 . 따라서 여기에서 따옴표를 조건부로 삭제하는 것은 매우 쉽습니다.

l           " Move one character to the right. If there is no character to the right, 
            " then this is effectively a "break" statement, stopping playback of the recording
 xx         " Delete two characters (the '"P')
   |        " Move to the first character on this line
    x       " Delete one character
     ÿ      " End the program

3

자바 스크립트 (ES6) 239 237 바이트

Set=``;eval(";a='Set=``;eval(~;a=1;S=String.fromCharCode;q=S(34);r=Set&&q;s=S(39);alert(r+a.replace(/[^ -}]/g,q).replace(1,s+a+s)+r);~)';S=String.fromCharCode;q=S(34);r=Set&&q;s=S(39);alert(r+a.replace(/[^ -}]/g,q).replace(1,s+a+s)+r);")

새로운 환경 (예 : 새 브라우저 탭)에서 각 버전을 시험해보십시오.

이것을 단순화하는 적어도 하나의 방법이 있어야합니다 ...


1
[x = "replace"]와 같이 교체 용 배열을 사용할 수 있다고 가정합니다. 그래도 물건을 깰 수도 있지만, 나는 quines에 대해별로 경험이 없습니다 ...
Luke
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.