Hyper về quines


27

Lấy cảm hứng từ Hyperprogramming: N + N, N × N, N ^ N tất cả trong một .
Cảm ơn @MartinEnder và @trichoplax vì sự giúp đỡ của họ trong hộp cát.

Định nghĩa

Hyperquines

Xác định một hyperquine của thứ tự n là một chương trình đầy đủ giống như quine hoặc hàm P thỏa mãn tất cả các quy tắc áp dụng cho các quines thích hợp và, ngoài ra, có cấu trúc như sau.

P là nối của nhân vật nhóm gồm n bản sao của cùng một ký tự. Khi P được thực thi, đầu ra là sự kết hợp của các nhóm giống nhau, được tăng thêm một bản sao của ký tự.

Ví dụ

  • Trong một ngôn ngữ lập trình giả thuyết nơi mã nguồn aabbcctạo ra đầu ra aaabbbccc, chương trình này tạo thành một siêu dữ liệu bậc 2 .

  • Định nghĩa không yêu cầu các ký tự của các nhóm khác nhau phải khác nhau.

    Nếu mã nguồn aabbcctạo ra đầu ra aaaabbbbcccc, chương trình là một siêu dữ liệu của đơn hàng 1 ; mã nguồn bao gồm sáu nhóm ký tự đơn, đầu ra của sáu cặp ký tự.

  • Trong GS2 , chương trình trống in \nvà chương trình \nin \n\n. Tuy nhiên, không phải \ncũng không phải \n\nlà hyperquines, vì chúng không thỏa mãn tất cả các thuộc tính của các quines thích hợp ; không có phần nào của mã nguồn mã hóa một phần khác của đầu ra.

Chuỗi hyperquine

Xác định một chuỗi hyperquine có độ dài n là một chuỗi hữu hạn của n chương trình đầy đủ hoặc n hàm
(P 1 , Vượt , P n ) thỏa mãn các ràng buộc sau.

  1. Đầu ra của P 1 , Lọ, P n-1 lần lượtP 2 , Rò, P n .

  2. P 1 , Lọ , P n là các siêu dữ liệu.

  3. Các đơn hàng của P 1 , tầm, P n tạo thành một chuỗi số nguyên liền kề tăng nghiêm ngặt .

Cuối cùng, định nghĩa một chuỗi hyperquine vô hạn là một chuỗi vô hạn của các chương trình hoặc hàm đầy đủ (P 1 , P 2 , CÁCH ) sao cho mỗi khoảng thời gian ban đầu (P 1 , một, P n ) tạo thành một chuỗi hyperquine có độ dài n .

Ví dụ

  • Trong ngôn ngữ lập trình giả thuyết, nơi mã nguồn aabbcctạo ra đầu ra aaabbbccc, do đó, tạo ra đầu ra aaaabbbbcccc, cặp ( aabbcc, aaabbbccc) tạo thành một chuỗi siêu liên kết có độ dài 2 .

    Lưu ý rằng aaaabbbbcccc- đầu ra của hyperquine cuối cùng trong chuỗi - không phải tạo ra một đầu ra cụ thể; nó thậm chí không phải là mã nguồn hợp lệ.

  • Tiếp tục ví dụ trước, nếu aaaabbbbccccphát sinh đầu ra aaaaabbbbbccccc, bộ ba ( aabbcc, aaabbbccc, aaaabbbbcccc) tạo thành một chuỗi hyperquine có độ dài 3 .

    Nếu mô hình này tiếp tục mãi mãi, trình tự ( aabbcc, aaabbbccc, aaaabbbbcccc, ...) tạo thành một chuỗi hyperquine vô hạn.

  • Cặp chương trình ( abc, aabbcc) có đầu ra ( aabbcc, aaaabbbbcccc) không phải là một chuỗi hyperquine, vì các lệnh của hyperquines đều là 1 , vì vậy chúng không tạo thành một chuỗi tăng nghiêm ngặt.

  • Cặp chương trình ( aabbcc, aaaabbbbcccc) có đầu ra ( aaaabbbbcccc, aaaaabbbbbccccc) không phải là chuỗi hyperquine, vì thứ tự của hyperquines là 14 , vì vậy chúng không tạo thành một chuỗi các số nguyên liền kề.

Quy tắc

Bài tập

Trong ngôn ngữ lập trình mà bạn chọn, hãy viết một chuỗi hyperquine không tầm thường, tức là một chuỗi bao gồm ít nhất 2 hyperquine.

Như thường lệ, các chương trình của bạn có thể không nhận bất kỳ đầu vào hoặc truy cập mã nguồn riêng của họ dưới bất kỳ hình thức nào.

Nếu trình thông dịch của bạn in một dòng mới ẩn, các siêu dữ liệu của bạn phải tính đến điều này.

Tất cả các sơ hở tiêu chuẩn - đặc biệt là những liên quan đến quines - áp dụng.

Chấm điểm

Chuỗi hyperquine dài nhất chiến thắng. Nếu hai hoặc nhiều bài nộp được ràng buộc, bài nộp trong số này bắt đầu bằng hyperquine ngắn nhất (tính bằng ký tự ) sẽ thắng. Như thường lệ, thời gian đăng bài là bản bẻ khóa cuối cùng.


Bạn phải sử dụng mã hóa ký tự tương tự cho mã nguồn, đầu ra, số ký tự, và thực hiện. Ví dụ, chương trình Python không phảiprint 42 là đệ trình UTF-32 gồm 2 ký tự, vì trình thông dịch coi mỗi byte là một ký tự đơn. Nếu ngôn ngữ bạn chọn không dựa trên ký tự, hãy coi tất cả các byte riêng lẻ là ký tự.


3
Được rồi, vì vậy có lẽ thách thức của Helka là không thể, nhưng chắc chắn đây là: D
Beta Decay

1
@BetaDecay Có thật không? :)
Martin Ender

Câu trả lời:


10

Befunge-98 , thứ tự vô hạn, 54 52 38 36 byte

Cách tiếp cận thứ hai - thứ tự vô hạn, 36 byte

Chương trình này thực sự sẽ phá vỡ ở hyperquine thứ 34 vì giá trị ASCII "sẽ phá vỡ việc giải thích chuỗi (và ở 59, ;), nhưng chúng tôi bù việc lưu trữ giá trị đó vào một vị trí sẽ không bao giờ được thực thi ( (0, 1)thay vì (0, 0)).

1+::0*x01pn'!1+:#jr;,kg10@k!:kg10;#"

Dùng thử trực tuyến: 1 , 2 , 10 , 34 , 42

Giải trình

INSTRUCTIONS  STACK (PYTHON PSEUDOCODE)           EXPLANATION
1+            [n]                                 Push n many 1s onto the stack, then sum them up
::            [n]*(at least 3)                    Duplicate that sum at least twice
0*            [n]*(at least 2)+[0]                Push a whole lot of zeros, then multiply them all together
x             [n]*(at least 1)                    Pop a vector off the stack (n, 0) and set the IP delta to that; now the IP is only executing every nth character
01p           [n]*(at least 1)                    Place n in the program at coordinates (0, 1); this is just for storage
n             []                                  Clear the stack
'!1+          ['"']                               '!' is character 33; one less than 34, or '"'
:#jr          ['"']                               We duplicate the 34 (all we care is that it's a rather large number), then turn around and skip that many spaces
                                                  The IP, having jumped 34*n instructions to the left, is now way in the negatives
                                                  Execution resumes on the other side of the program (the following instructions have been reversed for readability
"             [the program of order 1]            The quote-at-the-end-of-the-program is a common trick for one-liner Befunge quines
#; ... ;                                          Jumps into a loop (when the IP hits one semicolon it skips to the next, restarting the loop)
01gk:         [(rest of string), char*(n+2)]      This duplicates the letter n+1 times*, leaving n+2 copies on the stack
!k@                                                If the number on the top of the stack is zero (i.e. we are printing), it will execute '@',
                                                  ending the program; otherwise, it will NOT execute '@' and will instead continue normally
                                                  Vague* 'k' instruction FTW
10gk,                                             If we aren't done yet, print the character n+1 times* (and restart the loop)

* 'k' is a very strange instruction. It pops a number off the stack; if the number is zero, it skips the command in front of it. If the number is greater than zero,
  it will execute the instruction that many times PLUS ONE. This is actually strangely advantageous in this program.

Cách tiếp cận đầu tiên - thứ tự 34, 52 byte (sử dụng hướng nội, vì vậy về mặt kỹ thuật không hợp pháp)

Vì lý do trong bài viết trên, chương trình này sẽ phá vỡ ở thứ tự 34 (mặc dù tôi chưa thử nghiệm).

1+::0*x:00p'1\k:00gk,1#;:00g*0g00gk:$00gk,1+:'4-!k@;

Hãy thử trực tuyến!


2
Mặc dù kết quả đầu ra có vẻ chính xác và điều này chắc chắn rất ấn tượng, tôi không tin rằng một quine thích hợp có thể sử dụng g, dường như trực tiếp đọc mã nguồn của chương trình. Điều đó nói rằng, tôi hầu như không phải là một chuyên gia Befunge, vì vậy tôi có thể đang hiểu nhầm điều gì đó.
Dennis

Tôi đang sử dụng gcho hai mục đích ở đây: để lưu trữ dữ liệu và đọc mã nguồn. Cái thứ hai có thể hơi sơ sài, mặc dù esolangs.org/wiki/Befunge#Quine cũng có một ví dụ sử dụng gđể đọc mã nguồn. Trong lúc này, tôi sẽ xem liệu tôi có thể tạo một phiên bản không sử dụng bất kỳ nội quan nào không.
Hactar

Tôi biết điều này phải có ở Befunge, nhưng tôi không biết làm thế nào. Cảm ơn đã chỉ cho tôi. +1
Sản phẩm ETH

10

> <> , thứ tự vô hạn, 178 byte

Chương trình chứa một linefeed trailing.

^
.
*
&
:
&
+
*
2
b
*
*
6
9
$
0
)
*
4
8
:
~
.
*
&
:
&
+
*
2
b
*
*
2
b
$
0
)
i
:
-
1
o
a
&
:
&
o
~
.
*
&
:
&
+
*
7
7
*
*
4
6
$
0
)
0
:
-
1
$
o
:
$
&
:
&
&
,
*
8
b
-
1
l
}
*
3
d
'

Dùng thử trực tuyến: 1 , 2 , 3 , 10 (Cái cuối cùng cần một chút thời gian để chạy.)

Kịch bản Retina để tạo nguồn từ chương trình tuyến tính.

Giải trình

Ý tưởng chính là xoay trục dọc, sao cho luồng điều khiển thực tế không bị ảnh hưởng bởi sự lặp lại. Ví dụ: siêu quine thứ hai bắt đầu như:

^^

..

**

Vì chúng tôi chỉ di chuyển qua cột đầu tiên, chúng tôi không phải lo lắng về các ký tự lặp đi lặp lại. Ngoài ra khi chúng ta đẩy phần lớn mã dưới dạng một chuỗi ', điều này sẽ đẩy một khoảng trống cho mỗi dòng trống, điều này cho chúng ta một cách để xác định số lần lặp lại. Điều đó nói rằng, có một số hạn chế do những dòng trống này:

  • Chúng ta không thể sử dụng "để đẩy số lượng lớn làm mã ký tự trong phần chính của câu hỏi, bởi vì điều này sẽ đẩy thêm số 32mà chúng ta không muốn.
  • Chúng tôi không thể sử dụng ?hoặc !vì họ chỉ bỏ qua ký tự tiếp theo sẽ là khoảng trắng trong trường hợp đó (vì vậy họ thực sự sẽ không bỏ qua lệnh tiếp theo).

Do đó, tất cả các luồng điều khiển được thực hiện với các bước nhảy rõ ràng (2D goto, về cơ bản), có độ lệch thực tế mà chúng ta cần tính toán dựa trên số lần lặp lại.

Vì vậy, hãy nhìn vào mã thực tế. Chúng tôi bắt đầu với ^để mã được thực hiện từ dưới lên. Để dễ đọc hơn, hãy viết mã thực tế theo thứ tự thực hiện (và bỏ mã ^vì nó không bao giờ được thực hiện lại):

'd3*}l1-b8*,&&:&$:o$1-:0)0$64**77*+&:&*.~o&:&ao1-:i)0$b2**b2*+&:&*.~:84*)0$96**b2*+&:&*.

Đây 'là kỹ thuật quining tiêu chuẩn cho> <> (và Befunge, tôi đoán vậy). Nó chuyển sang chế độ chuỗi, có nghĩa là các ký tự gặp phải được đẩy lên ngăn xếp cho đến khi 'gặp tiếp theo . Các dòng trống được đệm hoàn toàn với các khoảng trắng, đó là lý do tại sao chúng ta có được tất cả các khoảng trắng ở giữa. Các dòng trống ở cuối chương trình được bỏ qua. Vì vậy, sau khi IP kết thúc và quay 'lại, chúng ta đã có cột đầu tiên của chương trình trên ngăn xếp, ngoại trừ 'chính nó.

Hãy xem cách chúng tôi sử dụng điều này để in toàn bộ chương trình.

d3*}    Put a 36 (the ') at the bottom of the stack. Now the stack holds
        a representation of the entire first column.
l1-     Push the depth of the stack, minus (so minus to ').
b8*,    Divide by 88. The original program has 89 lines. If we divide the 
        depth of the stack (minus 1) by 88, we get the order of the current
        hyperquine (due to all the spaces we've pushed).
&       Store the order of the hyperquine in the register.
        Begin of main loop:
&:&       Push a copy of the register onto the stack. Call that N.
          Begin of line-printing loop:
$:o$        Print a copy of the top character on the stack.
1-          Decrement N.
:0)         Check whether it's still positive (gives 0 or 1).
0$          Put a 0 underneath. This will be the x-coordinate of a jump.
64**        Multiply the conditional by 24. This is the number of commands
            in this inner loop.
77*+        Add this to 49, the offset of the end of the loop.
            The result is line we want to jump to in the order-1 hyperquine.
&:&*        Multiply by the order of the quine (so that we jump further on
            higher quine orders).
.         Jump. If N isn't zero yet, this repeats the inner loop. Otherwise
          we continue right here.
~         Discard N (now 0).
o         Output one last copy of the top character on the stack.
&:&       Push a copy of the register onto the stack. Call that N.
          Begin of linefeed-printing loop:
ao          Print a linefeed.
1-          Decrement N.
:i)         Check whether it's still non-negative (gives 0 or 1).
            The next bit is essentially the same loop structure as above,
            but with loop length 22 and offset 22:
0$
b2**
b2*+
&:&*
.         Jump. If N isn't -1 yet, this repeats the inner loop. Otherwise
          we continue right here.
          Begin of space-clearing loop:
~           Discard the top of the stack. On the first iteration this is the
            -1 from the previous loop. Afterwards, it's one of the spaces
            representing an empty line.
:84*)       Check if the top of the stack is a space.
            And another loop conditional. This one works the other way round:
            the difference is 54, which is the distance between the beginning
            of this loop and the main loop. The offset is the beginning
            of this loop, at 22 as above.
0$
96**
b2*+
&:&*
.         Jump. If the top of the stack is still a space this repeats the 
          inner loop. Otherwise we continue from the top of the main loop.

Chương trình chấm dứt khi ngăn xếp trống và vòng lặp bên trong đầu tiên không in được ký tự khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.