Hiper tentang quines

27

Terinspirasi oleh Hyperprogramming: N + N, N × N, N ^ N semuanya dalam satu .
Terima kasih kepada @MartinEnder dan @trichoplax untuk bantuan mereka di kotak pasir.

Definisi

Hyperquine

Tetapkan hyperquine of order n sebagai program penuh seperti-quine atau fungsi P yang memenuhi semua aturan yang berlaku untuk quine yang tepat dan, di samping itu, memiliki struktur berikut.

P adalah gabungan dari karakter grup yang terdiri dari n salinan dari karakter yang sama. Ketika P dieksekusi, outputnya adalah gabungan dari grup yang sama, ditambah oleh satu salinan karakter.

Contohnya

  • Dalam bahasa pemrograman hipotetis di mana kode sumber aabbccmenghasilkan output aaabbbccc, program ini merupakan hyperquine of order 2 .

  • Definisi ini tidak memerlukan karakter dari kelompok yang berbeda untuk berbeda.

    Jika kode sumber aabbccmenghasilkan output aaaabbbbcccc, program adalah hyperquine pesanan 1 ; kode sumber terdiri dari enam kelompok karakter tunggal, output dari enam pasangan karakter.

  • Di GS2 , program yang kosong dicetak \n, dan program yang \ndicetak \n\n. Namun, tidak \njuga \n\nhyperquine, karena mereka tidak memenuhi semua sifat quines yang tepat ; tidak ada bagian dari kode sumber yang mengkodekan bagian berbeda dari output.

Rantai hyperquine

Tentukan rantai panjang hyperquine n sebagai urutan terbatas dari n program penuh atau fungsi n
(P 1 , ..., P n ) yang memenuhi batasan berikut.

  1. Output dari P 1 , ..., P n-1 adalah P 2 , ..., P n , masing-masing.

  2. P 1 ,…, P n adalah hyperquine.

  3. Perintah P 1 , ..., P n membentuk urutan peningkatan ketat dari bilangan bulat yang berdekatan .

Akhirnya, tentukan rantai hyperquine tak terbatas sebagai urutan tak terbatas dari program atau fungsi penuh (P 1 , P 2 , ...) sedemikian rupa sehingga setiap interval awal (P 1 , ..., P n ) merupakan rantai panjang hyperquine n .

Contohnya

  • Dalam bahasa pemrograman hipotetis di mana kode sumber aabbccmenghasilkan output aaabbbccc, yang, pada gilirannya, menghasilkan output aaaabbbbcccc, pasangan ( aabbcc, aaabbbccc) membentuk rantai hyperquine dengan panjang 2 .

    Perhatikan bahwa aaaabbbbcccc- output dari hyperquine terakhir dalam rantai - tidak harus menghasilkan output spesifik; bahkan tidak harus menjadi kode sumber yang valid.

  • Melanjutkan contoh sebelumnya, jika aaaabbbbccccmenghasilkan output aaaaabbbbbccccc, triplet ( aabbcc, aaabbbccc, aaaabbbbcccc) merupakan rantai hyperquine panjang 3 .

    Jika pola ini terus selamanya, urutan ( aabbcc, aaabbbccc, aaaabbbbcccc, ...) merupakan rantai hyperquine tak terbatas.

  • Pasangan program ( abc, aabbcc) dengan output ( aabbcc, aaaabbbbcccc) bukan rantai hyperquine, karena urutan hyperquine keduanya 1 , sehingga mereka tidak membentuk urutan peningkatan yang ketat.

  • Pasangan program ( aabbcc, aaaabbbbcccc) dengan output ( aaaabbbbcccc, aaaaabbbbbccccc) bukan rantai hyperquine, karena urutan hyperquine adalah 1 dan 4 , sehingga mereka tidak membentuk urutan bilangan bulat yang berdekatan.

Aturan

Tugas

Dalam bahasa pemrograman pilihan Anda, tulis rantai hyperquine non-trivial, yaitu rantai yang terdiri dari setidaknya 2 hyperquine.

Seperti biasa, program Anda mungkin tidak mengambil input apa pun atau mengakses kode sumbernya sendiri dalam bentuk apa pun.

Jika penerjemah Anda mencetak baris baru yang tersirat, hyperquine Anda harus menjelaskan hal ini.

Semua celah standar - terutama yang terkait dengan quines - berlaku.

Mencetak gol

Rantai hyperquine terpanjang menang. Jika dua atau lebih kiriman diikat, kiriman di antara ini yang dimulai dengan hyperquine terpendek (diukur dalam karakter ) menang. Seperti biasa, waktu posting adalah tiebreak terakhir.


Anda harus menggunakan pengkodean karakter yang sama untuk kode sumber, output, jumlah karakter, dan eksekusi. Sebagai contoh, program Python print 42adalah tidak 2 karakter UTF-32 pengajuan, karena penafsir memperlakukan setiap byte sebagai karakter tunggal. Jika bahasa pilihan Anda tidak berbasis karakter, perlakukan semua byte sebagai karakter.

Dennis
sumber
3
Oke, jadi mungkin tantangan Helka bukan hal yang mustahil, tapi tentu saja ini adalah: D
Beta Decay
1
@ BetaDecay Benarkah? :)
Martin Ender

Jawaban:

10

Befunge-98 , urutan tak terbatas, 54 52 38 36 byte

Pendekatan kedua - urutan tak terbatas, 36 byte

Program ini akan benar-benar pecah pada hyperquine ke-34 karena nilai ASCII "akan mengganggu interpretasi string (dan pada 59, ;), tetapi kami mengimbangi penyimpanan nilai tersebut ke posisi yang tidak akan pernah dieksekusi (yaitu (0, 1)bukannya (0, 0)).

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

Cobalah online: 1 , 2 , 10 , 34 , 42

Penjelasan

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.

Pendekatan pertama - order 34, 52 byte (menggunakan introspeksi, jadi secara teknis tidak legal)

Untuk alasan di posting di atas, program ini akan rusak di urutan 34 (meskipun saya belum diuji).

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

Cobalah online!

Hactar
sumber
2
Sementara output tampaknya benar dan ini tentu mengesankan, saya tidak yakin quine yang tepat dapat digunakan g, yang tampaknya langsung membaca kode sumber program. Yang mengatakan, aku bukan ahli Befunge, jadi aku mungkin salah paham tentang sesuatu.
Dennis
Saya menggunakan guntuk dua tujuan di sini: untuk menyimpan data dan membaca kode sumber. Yang kedua mungkin agak samar, meskipun esolangs.org/wiki/Befunge#Quine memiliki contoh menggunakan guntuk membaca kode sumber juga. Sementara itu, saya akan melihat apakah saya dapat membuat versi yang tidak menggunakan introspeksi apa pun.
Hactar
Saya tahu ini harus dimungkinkan di Befunge, tetapi saya tidak tahu caranya. Terima kasih sudah menunjukkan padaku. +1
ETHproduk
10

> <> , urutan tak terbatas, 178 byte

Program ini berisi linefeed baris tambahan.

^
.
*
&
:
&
+
*
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
'

Cobalah online: 1 , 2 , 3 , 10 (Yang terakhir butuh beberapa saat untuk berjalan.)

Skrip retina untuk menghasilkan sumber dari program linear.

Penjelasan

Gagasan utamanya adalah mengubah quine vertikal, sehingga aliran kontrol aktual tidak terpengaruh oleh pengulangan. Misalnya hyper quine kedua dimulai seperti:

^^

..

**

Karena kita hanya bergerak melalui kolom pertama, kita tidak perlu khawatir tentang karakter yang diulang. Juga ketika kita mendorong sebagian besar kode sebagai string ', ini akan mendorong spasi untuk setiap baris kosong, yang memberi kita cara untuk menentukan jumlah pengulangan. Yang mengatakan, ada beberapa batasan karena baris kosong ini:

  • Kita tidak dapat menggunakan "untuk mendorong angka besar sebagai kode karakter di bagian utama quine, karena ini akan mendorong tambahan 32yang tidak kita inginkan.
  • Kami tidak dapat menggunakan ?atau !karena mereka hanya melewatkan karakter berikutnya yang akan menjadi spasi dalam kasus itu (sehingga mereka tidak akan benar-benar melewatkan perintah berikutnya).

Oleh karena itu, semua aliran kontrol dilakukan dengan lompatan eksplisit (goto 2D, pada dasarnya), yang offset sebenarnya yang perlu kita hitung berdasarkan jumlah pengulangan.

Jadi mari kita lihat kode yang sebenarnya. Kita mulai dengan ^begitu kode dieksekusi dari bawah ke atas. Untuk membaca lebih mudah, mari kita menuliskan kode aktual dalam urutan eksekusi (dan lepaskan kode ^karena tidak pernah dieksekusi lagi):

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

Ini 'adalah teknik quining standar untuk> <> (dan Befunge, saya kira). Ini beralih ke mode string yang berarti bahwa karakter yang ditemui didorong ke stack sampai yang berikutnya 'ditemui. Garis-garis kosong secara implisit diisi dengan spasi-spasi itulah sebabnya kami mendapatkan semua spasi di antaranya. Baris kosong di akhir program diabaikan. Jadi setelah IP membungkus dan klik 'lagi, kita punya kolom pertama dari program di stack, kecuali untuk 'dirinya sendiri.

Mari kita lihat bagaimana kita menggunakan ini untuk mencetak seluruh program.

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.

Program berakhir ketika tumpukan kosong dan loop dalam pertama gagal mencetak karakter lain.

Martin Ender
sumber