APL (158 자, 점수 = 4)
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
여기 Dyalog APL을 사용하고 있습니다. 0
식의 끝과 문자열의 끝 (앞에 '''
)에 (0 다음에 공백)을 추가하여주기 수를 하나씩 늘릴 수 있습니다 . 사이클 길이는 (# 0's) + 1
이고 표현식의 길이는 150 + 4*(cycle length))
입니다. 우리는 영원히 0을 추가 계속 가정하면, 점수가 Limit[(150 + 4*n)/(n - 1), n -> Infinity] = 4
어디 n
사이클 길이입니다.
사이클 길이가 6 인 예는 다음과 같습니다.
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0
0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0
0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0
0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0
0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0
0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0
0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0
0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1
0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0
192 자, 점수 = 2
'''{2≠⍴⍺:¯3⌽(2×1+⍴⍺)⍴(1+⍴⍺)⍴⍺ ⋄ a←⊃2⌷⍺ ⋄ ⍵=0:¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a⋄(-4+⌊10⍟⊃⍺)⌽(2×1+⍴a)⍴(1+⍴a)⍴a}01'''{2≠⍴⍺:¯3⌽(2×1+⍴⍺)⍴(1+⍴⍺)⍴⍺⋄a←⊃2⌷⍺⋄⍵=0:¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a⋄(-4+⌊10⍟⊃⍺)⌽(2×1+⍴a)⍴(1+⍴a)⍴a}01
구현에 따라 문자열 앞에 붙은 정수가 너무 큰 경우 실패 지점이 될 수 있습니다. 그러나 이론적으로 1
문자열 끝에 (a 이전 '''
) 및 1
전체 줄 끝에 두 개의 문자를 추가하여주기를 추가 할 수 있습니다 .
200 자, 점수 = 1
'''{a←{2=⍴⍵:⊃2⌷⍵⋄⍵}⍺⋄(⍺{⍵=9:⍬⋄⍕1+{2=⍴⍵:10×⊃⍵⋄0}⍺}⍵),(¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a),⍺{⍵=9:(⍕9),⍕⊃⍺⋄⍕⌊⍵÷10}⍵}'''{a←{2=⍴⍵:⊃2⌷⍵⋄⍵}⍺⋄(⍺{⍵=9:⍬⋄⍕1+{2=⍴⍵:10×⊃⍵⋄0}⍺}⍵),(¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a),⍺{⍵=9:(⍕9),⍕⊃⍺⋄⍕⌊⍵÷10}⍵}91
내 APL 구현에는 기본적으로 무제한 정밀도 정수가 없으므로 너무 커지면 정수가 부동 소수점으로 변환되어 출력이 잘못됩니다. 따라서 이것은 가장 까다 롭지 만 이론적으로는 (손으로 또는 다른 APL 인터프리터와 함께) 점수가 1이어야 1
합니다. 식의 끝에 a 를 추가 하면 다른 사이클이 생깁니다.
개요 (짧은 퀴인)
첫 번째 버전에 대한 개요를 제공 할 것입니다. 아마도 이해하기 가장 쉬운 방법이라고 생각하기 때문입니다. 그러나 그 버전을 다루기 전에 APL에서 간단한 퀘인 을 고려할 것입니다 .
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
일부 APL 표현식을 이해하는 가장 좋은 방법 중 하나는 일련의 연산자 / 함수 전체에서 출력을 보는 것입니다. APL의 모든 연산자와 함수는 오른쪽 연관이며 우선 순위가 동일하므로 오른쪽에서 왼쪽으로 있습니다.
'''1⌽22⍴11⍴'''
: 이것은 문자열 리터럴 (문자 목록)입니다. ''
작은 따옴표를 이스케이프 처리하는 APL 방식입니다. 출력 : '1⌽22⍴11⍴'
.
11⍴'''1⌽22⍴11⍴'''
: 여기서 우리 ⍴
는 문자열의 길이를 변경 11
합니다. 문자열의 길이가 11 미만이므로 반복됩니다 (즉, 5⍴'abc'
yield 'abcab'
). 출력 : '1⌽22⍴11⍴''
. 이제 끝에 두 개의 따옴표가 있습니다. 어딘가에 있습니다!
22⍴11⍴'''1⌽22⍴11⍴'''
: 마찬가지로, 우리는 이제 이전 출력 길이를 길이로 변경 22
합니다. 출력 : '1⌽22⍴11⍴'''1⌽22⍴11⍴''
. 거의 다 왔습니다. 첫 작은 따옴표를 끝까지 이동하면됩니다.
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
: 여기서 ⌽
문자 목록을로 회전시킵니다 ( ) 1
. 문자열의 첫 문자가 끝으로 이동합니다. 다른 예로,을 2⌽'abcdef'
반환합니다 'cdefab'
. 출력 : 1⌽22⍴11⍴'''1⌽22⍴11⍴'''
.
회전하는 퀴네
그 짧은 퀴네는 우리의 회전하는 퀴네의 기본입니다. 이제, 그것을 염두에두고, 우리의 quine을 살펴 봅시다 :
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
{ ... }
우리가 작업을 수행 할 이름없는 함수를 정의합니다. APL의 함수는로 표시된 오른쪽 인수 ⍵
와 ⍺
(사고라고 생각 되는) 선택적 왼쪽 인수를 사용 합니다. 우리는이 함수를 quine string과 임의의 수의 사이클을 만드는 데 도움이되는 것을 제공하려고합니다. 우리 자신과 사이클을 추가하려는 사람을 쉽게하기 위해 quine 문자열을 왼쪽 인수로 만듭니다. 그렇다면 올바른 주장은 우리가주기 목록을 넣는 곳입니다. 공백으로 구분 된 2 개 이상의 항목이 목록을 생성하므로이 예에서는 a 1
및 a 로 구성된 2 요소 목록 이 0
있습니다.
우리는 함수가 이전의 quine과 비슷하게 보이는 것을 볼 수 있습니다. 우리는 ...⌽...⍴...⍴...
이전 과 같은 형태입니다. 그래서 그것은 좋습니다-우리는 적어도 그 정도를 이해합니다! 의 마지막 후 모든 것을 시작으로 타원 더 깊이 탐구 보자 ⍴
: ⊃,/(~^/¨⍺=0)/⍺
.
- 위의 예를 보면 알 수 있듯이 오른쪽에서 문자열 앞에 0을 붙여 각 반복마다 하나씩 추가합니다. 하지만 지금은 신경 쓰지 않습니다. 우리는 단지 문자열을 원한다!
- 먼저 괄호 안에 무엇이 있는지 고려하십시오. (그들은 대부분의 다른 언어와 마찬가지로 그룹화합니다.)
⍺=0
이 경우와 같은 모양을 가진 목록을 반환합니다. ⍺
여기서 각 요소 ⍺
는 1
if 0
와 같고 0
그렇지 않으면입니다. 이것은 재귀 적으로 수행됩니다. 따라서 문자 목록의 목록이 있으면 개별 문자가 0에 대해 테스트되고 이진 값 목록의 목록이 다시 표시됩니다.
- 따라서
⍺
문자열로만 구성된 경우 0 목록을 다시 얻습니다. 그렇지 않으면 왼쪽 인수에 접두사가 붙습니다 (예 :). 0 0 0 'quinestring'
0과 문자열로 구성된 목록입니다. 그런 다음 출력은 다음과 같습니다 1 1 1 <sub-list of zeros>
.
^/¨⍺=0
: 논리 AND ( ) 함수를 사용하여 ^/
( /
)를 줄인 파생 함수 를의 ( ^
) 각 ¨
요소에 적용 ⍺=0
합니다. 이것은 퀴네 문자열을 하나의 이진 값으로 간주 할 수 있도록 0의 하위 목록을 평평하게하는 것입니다. 이전 예제를 고려하면 출력은입니다 1 1 1 0
.
~
: 이전의 각 값을 이진수로 변환하지 않습니다 (예 :) 0 0 0 1
.
(~^/¨⍺=0)/⍺
:의 각 요소 에 대해 왼쪽 인수의 해당 요소가 지정한 횟수를 ⍺
복제합니다 ( /
). 이것은 0을 모두 제거하고 퀴네 문자열 만 남겨 둡니다.
⊃,/
연결 함수 ( ,
)로 결과를 줄임으로써 평평한 문자 목록을 다시 얻을 수 있도록하기 위해 필요한 서류 입니다. 입력이 이미 평탄화 된 목록 인 경우 (즉, 기본 함수의 왼쪽 인수가 문자열 일 경우) 해당 목록을 포함하는 1 요소 목록을 얻습니다. 다른 경우에는 문자열의 하위 목록으로 구성된 목록이 있으면 동일한 항목 (하위 목록이있는 목록)을 가져옵니다. 그런 다음이 패키지 ( ⊃
)의 압축을 풀고 목록의 첫 번째 요소 (예 : 문자의 하위 목록) 만 제공합니다. 이것은 불필요하게 보일 수 있지만, 그렇지 않으면 우리는 1 요소리스트의 형태를 변경하려고 할 것입니다!
다음으로, 우리는 괄호 안에있는 첫 번째 모양 변경에 주어진 길이를 살펴 봅니다 :
⍺,⍵
: 우리는 올바른 주장을 첫 번째 주장에 연결합니다
⊃,/⍺,⍵
: 이전과 동일-목록을 평평하게합니다.
+/0=⊃,/⍺,⍵
: 더하기 /
( +
) 기능을 사용하여 ( )를 줄임으로써 목록에 0의 수를 더하십시오 .
2×+/0=⊃,/⍺,⍵
: 그 숫자에 2를 곱하십시오.
z←2×+/0=⊃,/⍺,⍵
: ←
결과를 변수에 지정합니다 ( ) z
. 요약하면, z
왼쪽과 오른쪽 인수 모두에서 발견되는 0의 두 배입니다.
77+z←2×+/0=⊃,/⍺,⍵
다음으로 77
퀴네 문자열의 문자에 공백 뒤에 오는 모든 것을 무시하고을 추가합니다 1
. 초기 quine 예제와 마찬가지로 문자열의 길이에 1을 더하여 작은 따옴표를 얻습니다.
- 이 예에서이 변형의 출력은 다음과 같습니다.
'{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 ''
뒤 따르는 형태 변경에 대한 논증은 간단하며 짧은 퀴인 (첫 번째 형태의 길이의 2 배)을 반영합니다. 우리의 결과는 다음과 같습니다.
'{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 ''
이제 출력 문자열 회전 정도를 계산하는 마지막 단계는 다음과 같습니다.
- 이전 출력을 보면 알 수 있듯이 두 개의 마지막 따옴표를 처음으로 가져 오기 위해 다시 회전 (음수)합니다. 우리는 또한
0
(그리고 다른 공간) 시작 부분으로 이동하기를 원하기 때문에 추가로 3 자 뒤로 회전하고 싶습니다.
+/+/¨⍺=0
: 왼쪽 인수 에 0의 수를 더하십시오 . 첫 번째 (오른쪽부터) +/¨
는 각 요소의 개수 (예 : 하위 목록 또는 정수)를 +/
합산 하고 두 번째 는 결과 목록의 합계를 제공합니다.
5+2×+/+/¨⍺=0
: 2를 곱하고 (공백도 회전) 5를 더합니다 (이전에 나온 결과).
- 이제
-
우리는 사이클의 끝에 도달했을 때를 처리 하기 위해 왼쪽 인수에서 이전 값을 뺍니다 .
(3+z)×^/⍵
: 그리고 올바른 인수의 모든 요소를 함께 사용하여 끝 ( 1
)에 도달했는지 확인 하고을 곱하십시오 3+z
.
그리고 우리는 끝났습니다!