Hyper o quinesach

27

Inspirowane hiperprogramowaniem: N + N, N × N, N ^ N wszystko w jednym .
Dzięki @MartinEnder i @trichoplax za pomoc w piaskownicy.

Definicje

Hyperquines

Zdefiniuj hiperquinę rzędu n jako pełny program lub funkcję P przypominającą quine, która spełnia wszystkie reguły mające zastosowanie do odpowiednich quines, a ponadto ma następującą strukturę.

P jest konkatenacją znaków grup składających się z n kopii tego samego znaku. Kiedy P jest wykonywane, wynikiem jest konkatenacja tych samych grup, powiększona o jeszcze jedną kopię znaku.

Przykłady

  • W hipotetycznym języku programowania, w którym kod źródłowy aabbccgeneruje dane wyjściowe aaabbbccc, program ten stanowi hiperquinę rzędu 2 .

  • Definicja nie wymaga, aby znaki z różnych grup były różne.

    Jeśli kod źródłowy aabbccgeneruje dane wyjściowe aaaabbbbcccc, program jest hiperquine rzędu 1 ; kod źródłowy składa się z sześciu jednoznakowych grup, a wynik sześciu par znaków.

  • W GS2 pusty program jest drukowany \n, a program jest \ndrukowany \n\n. Jednak \nani \n\nhiperquiny, ani te nie są, ponieważ nie spełniają one wszystkich właściwości właściwych quines ; żadna część kodu źródłowego nie koduje innej części wyniku.

Łańcuchy Hyperquine

Zdefiniuj hiperquinowy łańcuch długości n jako skończoną sekwencję n pełnych programów lub n funkcji
(P 1 ,…, P n ), która spełnia następujące ograniczenia.

  1. Wyjściami P 1 ,…, P n-1 są odpowiednio P 2 ,…, P n .

  2. P 1 ,…, P n są hiperkwinami.

  3. Rzędy P 1 ,…, P n tworzą ściśle rosnącą sekwencję sąsiednich liczb całkowitych.

Na koniec zdefiniuj nieskończony łańcuch hiperquinowy jako nieskończoną sekwencję pełnych programów lub funkcji (P 1 , P 2 ,…) tak, aby każdy początkowy przedział (P 1 ,…, P n ) stanowił łańcuch hiperquinowy o długości n .

Przykłady

  • W hipotetycznym języku programowania, w którym kod źródłowy aabbccgeneruje dane wyjściowe aaabbbccc, które z kolei generują dane wyjściowe aaaabbbbcccc, para ( aabbcc, aaabbbccc) stanowi hiperquinowy łańcuch o długości 2 .

    Zauważ, że aaaabbbbcccc- wynik ostatniej hiperquiny w łańcuchu - nie musi generować określonego wyniku; nie musi to być nawet poprawny kod źródłowy.

  • Kontynuując poprzedniego przykładu, jeśli aaaabbbbccccwytwarza sygnał wyjściowy aaaaabbbbbccccc, trójkę ( aabbcc, aaabbbccc, aaaabbbbcccc) stanowi łańcuch hyperquine długości 3 .

    Jeśli ten wzór trwa wiecznie, sekwencja ( aabbcc, aaabbbccc, aaaabbbbcccc, ...) stanowi nieskończony łańcuch hyperquine.

  • Para programów ( abc, aabbcc) z wyjściami ( aabbcc, aaaabbbbcccc) nie jest łańcuchem hiperquin, ponieważ oba rzędy hiperquin są równe 1 , więc nie tworzą ściśle rosnącej sekwencji.

  • Para programów ( aabbcc, aaaabbbbcccc) z wyjściami ( aaaabbbbcccc, aaaaabbbbbccccc) nie jest łańcuchem hiperquin, ponieważ rzędy hiperquin to 1 i 4 , więc nie tworzą one sekwencji sąsiednich liczb całkowitych.

Zasady

Zadanie

W wybranym języku programowania napisz nietrywialny łańcuch hiperquinowy, tj. Łańcuch składający się z co najmniej 2 hiperkwin.

Jak zwykle, twoje programy nie mogą pobierać żadnych danych wejściowych ani uzyskiwać dostępu do własnego kodu źródłowego w żadnej formie.

Jeśli twój interpreter wypisuje ukrytą nową linię, hiperquiny muszą to uwzględnić.

Obowiązują wszystkie standardowe luki - zwłaszcza te związane z quinesami.

Punktacja

Najdłuższy łańcuch hiperquiny wygrywa. Jeśli dwa lub więcej zgłoszeń jest powiązanych, zgłoszenie spośród tych, które zaczyna się od najkrótszej hiperquiny (mierzonej w znakach ) wygrywa. Jak zwykle czas publikacji jest ostatecznym rozstrzygnięciem.


Musisz użyć tego samego kodowania znaków dla kodu źródłowego, wyniku, liczby znaków i wykonania. Na przykład, program Python print 42jest nie 2 znaków UTF-32 uległość, ponieważ interpreter traktuje każdy bajt jako pojedynczego znaku. Jeśli wybrany język nie jest oparty na znakach, wszystkie bajty należy traktować jak znaki.

Dennis
źródło
3
Okej, więc może wyzwanie Helki nie było niemożliwe, ale na pewno jest to: D
Rozpad
1
@BetaDecay Czy to naprawdę? :)
Martin Ender

Odpowiedzi:

10

Befunge-98 , nieskończony porządek, 54 52 38 36 bajtów

Drugie podejście - nieskończony porządek, 36 bajtów

Ten program faktycznie pękłby na 34. hiperkwinie, ponieważ wartość ASCII "zakłóciłaby interpretację łańcucha (i na 59 ;), ale przesunęliśmy zapis tej wartości do pozycji, która nigdy nie zostanie wykonana (tj. (0, 1)Zamiast (0, 0)).

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

Wypróbuj online: 1 , 2 , 10 , 34 , 42

Wyjaśnienie

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.

Pierwsze podejście - zamów 34, 52 bajty (wykorzystuje introspekcję, więc technicznie nie jest legalne)

Z powodu w powyższym poście program ten zepsuje się przy zamówieniu 34 (chociaż nie testowałem).

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

Wypróbuj online!

Haktar
źródło
2
Chociaż wyniki wydają się być poprawne i jest to z pewnością imponujące, nie jestem przekonany, że można użyć odpowiedniego quine g, który wydaje się bezpośrednio odczytywać kod źródłowy programu. To powiedziawszy, nie jestem ekspertem Befunge, więc mogę coś źle zrozumieć.
Dennis,
Używam gtutaj do dwóch celów: do przechowywania danych i odczytu kodu źródłowego. Drugi może być trochę szkicowy, nawet jeśli esolangs.org/wiki/Befunge#Quine ma również przykład użycia gdo odczytu kodu źródłowego. W międzyczasie zobaczę, czy mogę stworzyć wersję, która nie korzysta z introspekcji.
Haktar
Wiedziałem, że to musi być możliwe w Befunge, ale nie miałem pojęcia, jak to zrobić. Dzięki za pokazanie mi. +1
ETHprodukcje
10

> <> , nieskończony porządek, 178 bajtów

Program zawiera końcowy kanał.

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

Wypróbuj online: 1 , 2 , 3 , 10 (Uruchomienie tego ostatniego zajmuje trochę czasu).

Skrypt Retina do generowania źródła z programu liniowego.

Wyjaśnienie

Główną ideą jest obrócenie go w pionie, aby powtórzenie nie wpłynęło na rzeczywisty przepływ sterowania. Np. Druga hiper-quina zaczyna się tak:

^^

..

**

Ponieważ poruszamy się tylko w pierwszej kolumnie, nie musimy się martwić o powtarzające się postacie. Również gdy popchniemy większość kodu jako ciąg znaków ', spowoduje to wypchnięcie spacji dla każdej pustej linii, co daje nam sposób na określenie liczby powtórzeń. To powiedziawszy, istnieją pewne ograniczenia z powodu tych pustych linii:

  • Nie możemy używać "do wypychania dużych liczb jako kodów znaków w głównej części quine, ponieważ spowodowałoby to wypchnięcie dodatkowych liter, 32których nie chcieliśmy.
  • Nie możemy użyć ?lub !ponieważ pomijają tylko następną postać, która w tym przypadku byłaby spacją (więc nie pominęliby następnego polecenia).

Stąd cały przepływ sterowania odbywa się za pomocą jawnych skoków (zasadniczo goto 2D), których rzeczywiste przesunięcia musimy obliczyć na podstawie liczby powtórzeń.

Spójrzmy więc na rzeczywisty kod. Zaczynamy od, ^więc kod jest wykonywany oddolnie. Aby ułatwić czytanie, wypiszmy aktualny kod w kolejności wykonania (i upuść, ^ponieważ nigdy więcej nie zostanie wykonany):

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

Jest 'to standardowa technika quiningu dla> <> (i, jak sądzę, Befunge). Przełącza się na tryb ciągów, co oznacza, że ​​napotkane znaki są wypychane na stos aż do 'napotkania następnego . Puste linie są domyślnie wypełnione spacjami, dlatego otrzymujemy wszystkie spacje między nimi. Puste linie na końcu programu są ignorowane. Więc po tym, jak IP zawija się i uderza 'ponownie, mamy pierwszą kolumnę programu na stosie, z wyjątkiem 'samej.

Zobaczmy, jak wykorzystujemy to do wydrukowania całego programu.

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 kończy się, gdy stos jest pusty, a pierwsza wewnętrzna pętla nie wypisuje innego znaku.

Martin Ender
źródło