APL (158 ký tự, điểm = 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
Tôi đang sử dụng Dyalog APL ở đây. Số lượng chu kỳ có thể được tăng thêm bằng cách thêm 0
(0 theo sau là khoảng trắng) vào cuối biểu thức và vào cuối chuỗi (trước '''
). Độ dài chu kỳ là (# 0's) + 1
và độ dài của biểu thức là 150 + 4*(cycle length))
. Giả sử chúng ta tiếp tục thêm số không mãi mãi, điểm số là Limit[(150 + 4*n)/(n - 1), n -> Infinity] = 4
, n
độ dài chu kỳ.
Đây là một ví dụ với độ dài chu kỳ = 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 ký tự, điểm = 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
Tùy thuộc vào việc thực hiện, một điểm thất bại có thể là khi số nguyên có tiền tố cho chuỗi quá lớn. Tuy nhiên, về mặt lý thuyết, chúng ta có thể thêm một chu kỳ bằng cách thêm hai ký tự - một 1
ở cuối chuỗi (trước '''
) và 1
ở cuối toàn bộ dòng.
200 ký tự, điểm = 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
Việc triển khai APL của tôi không có số nguyên chính xác không giới hạn theo mặc định, do đó, số nguyên được chuyển đổi thành số float khi nó trở nên quá lớn, khiến đầu ra bị sai. Vì vậy, cái này là khó nhất, nhưng về mặt lý thuyết (bằng tay hoặc với một trình thông dịch APL khác), nó sẽ có điểm 1. Chỉ cần thêm một 1
vào cuối biểu thức, và bạn sẽ có một chu kỳ khác.
Tổng quan (với một câu hỏi ngắn hơn)
Tôi sẽ đưa ra một cái nhìn tổng quan về phiên bản đầu tiên, bởi vì tôi nghĩ nó có lẽ dễ hiểu nhất. Tuy nhiên, trước khi giải quyết phiên bản đó, chúng tôi sẽ xem xét một câu hỏi đơn giản trong APL :
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
Tôi đã thấy rằng một trong những cách tốt nhất để hiểu một số biểu thức APL là xem xét đầu ra trong toàn bộ các toán tử / hàm. Tất cả các toán tử và hàm trong APL đều liên kết phải và có cùng mức ưu tiên, vì vậy đây là, từ phải sang trái:
'''1⌽22⍴11⍴'''
: Đây chỉ là một chuỗi ký tự (một danh sách các ký tự). ''
là cách APL để thoát dấu ngoặc đơn. Đầu ra : '1⌽22⍴11⍴'
.
11⍴'''1⌽22⍴11⍴'''
: Ở đây, chúng tôi định hình lại ( ⍴
) chuỗi có độ dài 11
. Bởi vì độ dài của chuỗi dưới 11, nên nó được lặp lại (nghĩa là 5⍴'abc'
sẽ mang lại 'abcab'
). Đầu ra : '1⌽22⍴11⍴''
. Vì vậy, bây giờ chúng tôi có hai dấu ngoặc kép ở cuối - chúng tôi đang nhận được ở đâu đó!
22⍴11⍴'''1⌽22⍴11⍴'''
: Tương tự, bây giờ chúng tôi định hình lại đầu ra trước đó của chúng tôi có độ dài 22
. Đầu ra : '1⌽22⍴11⍴'''1⌽22⍴11⍴''
. Chúng ta gần đến rồi - chúng ta chỉ cần chuyển trích dẫn đầu tiên đến cuối.
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
: Ở đây, chúng tôi xoay ( ⌽
) danh sách các ký tự theo 1
. Điều này di chuyển ký tự đầu tiên của chuỗi đến cuối. Một ví dụ khác, 2⌽'abcdef'
trả về 'cdefab'
. Đầu ra : 1⌽22⍴11⍴'''1⌽22⍴11⍴'''
.
Các quine quay
Quine ngắn đó là cơ sở chính cho quine quay của chúng tôi. Bây giờ, với ý nghĩ đó, chúng ta hãy nhìn vào câu hỏi của chúng tôi:
'''{(((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
{ ... }
định nghĩa một hàm không tên, đó là nơi chúng ta sẽ thực hiện công việc. Lưu ý rằng các hàm trong APL có một đối số bên phải, được biểu thị bởi ⍵
và một đối số bên trái tùy chọn, được ký hiệu là ⍺
(think infix). Chúng tôi muốn cung cấp cho hàm này cả chuỗi quine của chúng tôi và một cái gì đó để hỗ trợ chúng tôi tạo ra một số chu kỳ tùy ý. Để làm cho mọi thứ dễ dàng hơn với chính chúng tôi (và bất kỳ ai muốn thêm chu kỳ), chúng tôi tạo chuỗi quine thành đối số bên trái. Đối số đúng, sau đó, là nơi chúng ta đặt danh sách các chu kỳ. 2 hoặc nhiều mục được phân tách bằng dấu cách sẽ tạo một danh sách, vì vậy trong ví dụ này, chúng ta có danh sách 2 phần tử bao gồm a 1
và a 0
.
Chúng ta có thể thấy rằng hàm trông tương tự như quine từ trước. Chúng tôi có ...⌽...⍴...⍴...
hình thức tương tự từ trước. Vậy là tốt rồi - ít nhất chúng ta cũng hiểu điều đó! Chúng ta hãy đi sâu hơn vào các hình elip, bắt đầu với mọi thứ sau cái cuối cùng ⍴
: ⊃,/(~^/¨⍺=0)/⍺
.
- Như bạn có thể thấy bằng cách xem ví dụ ở trên, chúng tôi tiền tố chuỗi có 0 từ phía bên tay phải, thêm một chuỗi với mỗi lần lặp; nhưng chúng tôi không quan tâm đến những người ngay bây giờ. Chúng tôi chỉ muốn chuỗi!
- Đầu tiên, hãy xem xét những gì trong ngoặc đơn. (Nhân tiện, họ nhóm như trong hầu hết các ngôn ngữ khác.)
⍺=0
trả về một danh sách, trong trường hợp này, có cùng hình dạng với ⍺
, trong đó mỗi phần tử trong ⍺
được thay thế bằng một 1
nếu nó bằng 0
và 0
khác. Điều này được thực hiện đệ quy; Vì vậy, nếu chúng tôi có một danh sách danh sách các danh sách các ký tự, các ký tự riêng lẻ sẽ được kiểm tra so với 0 và bạn sẽ nhận lại danh sách danh sách các danh sách các giá trị nhị phân.
- Vì vậy, nếu chỉ
⍺
bao gồm chuỗi của chúng tôi, chúng tôi sẽ lấy lại danh sách 0. Mặt khác, đối số bên trái của chúng tôi có một số 0 có tiền tố với nó (ví dụ 0 0 0 'quinestring'
:), vì vậy nó là một danh sách bao gồm 0 và một danh sách khác, chuỗi của chúng tôi. Sau đó, đầu ra của chúng tôi trông như thế 1 1 1 <sub-list of zeros>
.
^/¨⍺=0
: Chúng tôi áp dụng hàm dẫn xuất ^/
, làm giảm ( /
) bằng cách sử dụng hàm AND ( ^
) logic , cho từng ¨
phần tử ( ) của ⍺=0
. Điều này là để làm phẳng danh sách con của các số 0 để chúng ta có thể coi chuỗi quine là một giá trị nhị phân. Xem xét ví dụ trước, đầu ra sẽ là 1 1 1 0
.
~
: Chúng tôi nhị phân KHÔNG từng giá trị từ trước (ví dụ: trả về 0 0 0 1
).
(~^/¨⍺=0)/⍺
: Đối với mỗi phần tử trong ⍺
, chúng tôi sao chép ( /
) số lần được cho bởi phần tử tương ứng trong đối số bên trái. Điều này giúp loại bỏ tất cả 0, chỉ còn lại chúng ta với chuỗi quine.
⊃,/
là một số giấy tờ cần thiết để đảm bảo rằng chúng tôi lấy lại danh sách các ký tự được làm phẳng, bằng cách giảm kết quả với hàm ghép ( ,
). Nếu đầu vào đã là một danh sách dẹt (nghĩa là đối số bên trái cho hàm chính của chúng ta chỉ là chuỗi), chúng ta sẽ nhận được danh sách 1 phần tử có chứa danh sách đó. Trong trường hợp khác, khi chúng tôi có một danh sách bao gồm một danh sách phụ cho chuỗi, chúng tôi sẽ nhận lại điều tương tự (một danh sách có danh sách phụ). Sau đó, chúng tôi giải nén this ( ⊃
), chỉ cung cấp cho chúng tôi phần tử đầu tiên của danh sách (nghĩa là danh sách phụ của các ký tự). Điều này có vẻ không cần thiết, nhưng nếu không thì chúng tôi sẽ cố gắng định hình lại danh sách 1 yếu tố!
Tiếp theo, chúng tôi xem xét độ dài được đưa ra cho lần định hình lại đầu tiên, trong ngoặc đơn:
⍺,⍵
: Chúng tôi nối đối số đúng với đối số đầu tiên
⊃,/⍺,⍵
: Tương tự như trước - làm phẳng danh sách.
+/0=⊃,/⍺,⍵
: Cộng số lượng số không trong danh sách bằng cách giảm ( /
) bằng cách sử dụng hàm phép cộng ( +
).
2×+/0=⊃,/⍺,⍵
: Nhân số đó với hai.
z←2×+/0=⊃,/⍺,⍵
: Gán ( ←
) kết quả cho một biến , z
. Tóm lại, z
bây giờ gấp đôi số không tìm thấy trong cả hai đối số bên trái và bên phải.
77+z←2×+/0=⊃,/⍺,⍵
: Sau đó 77
, chúng tôi thêm , cho các ký tự trong chuỗi quine, bỏ qua mọi thứ sau khoảng trắng theo sau 1
. Giống như trong ví dụ quine ban đầu, chúng ta thêm 1 vào độ dài của chuỗi để có được một trích dẫn khác.
- Đầu ra của việc định hình lại này, trong ví dụ này là:
'{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 ''
Đối số cho việc định hình lại theo sau là đơn giản và phản ánh quine ngắn (gấp 2 lần chiều dài cho lần định hình lại đầu tiên). Đầu ra của chúng tôi bây giờ là:
'{(((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 ''
Bây giờ là bước cuối cùng, trong đó chúng tôi tính toán mức độ xoay chuỗi đầu ra:
- Như bạn có thể thấy bằng cách nhìn vào đầu ra trước đó, chúng tôi muốn xoay nó trở lại (một số âm) để đưa 2 dấu ngoặc kép cuối cùng vào đầu. Bởi vì chúng tôi cũng muốn một
0
(và một không gian khác) di chuyển về đầu, chúng tôi muốn xoay nó thêm 3 ký tự.
+/+/¨⍺=0
: Cộng số lượng số không trong đối số bên trái . Đầu tiên (từ bên phải) tính +/¨
tổng của từng phần tử (nghĩa là một danh sách con hoặc chỉ một số nguyên) và phần thứ hai +/
cung cấp cho chúng ta tổng của danh sách kết quả đó.
5+2×+/+/¨⍺=0
: Nhân với hai (để xoay các khoảng trắng) và thêm 5 (kết quả chúng tôi đã đưa ra trước đó).
- Bây giờ, chúng tôi trừ giá trị trước đó khỏi đối số bên trái
-
để xử lý trường hợp khi chúng tôi kết thúc chu kỳ:
(3+z)×^/⍵
: VÀ tất cả các yếu tố trong đối số phù hợp với nhau để xem liệu chúng ta đã đạt đến kết thúc ( 1
) và nhân số đó với 3+z
.
Và chúng ta đã hoàn thành!