Гипер о морях

27

Вдохновленный гиперпрограммированием: N + N, N × N, N ^ N все в одном .
Спасибо @MartinEnder и @trichoplax за их помощь в песочнице.

Определения

Hyperquines

Определите гиперхине порядка n как полную программу или функцию P , аналогичную квине , которая удовлетворяет всем правилам, применимым к правильным квинам, и, кроме того, имеет следующую структуру.

P - объединение групп символов , состоящих из n копий одного и того же символа. Когда P выполняется, выводом является конкатенация тех же групп, дополненная еще одной копией символа.

Примеры

  • На гипотетическом языке программирования, где исходный код aabbccгенерирует выходные данные aaabbbccc, эта программа представляет собой гиперхин порядка 2 .

  • Определение не требует, чтобы символы разных групп были разными.

    Если исходный код aabbccгенерирует выходные данные aaaabbbbcccc, программа является гиперхинейой порядка 1 ; Исходный код состоит из шести односимвольных групп, вывод из шести пар символов.

  • В GS2 пустая программа печатает \n, и программа \nпечатает \n\n. Однако ни гиперхины , ни они \nне \n\nявляются, так как они не удовлетворяют всем свойствам собственных хининов ; ни одна часть исходного кода не кодирует другую часть вывода.

Гиперквиновые цепи

Определите гиперхиневу цепочку длины n как конечную последовательность из n полных программ или n функций
(P 1 ,…, P n ), которая удовлетворяет следующим ограничениям.

  1. Выходы P 1 ,…, P n-1 равны P 2 ,…, P n соответственно.

  2. P 1 ,…, P n - гиперхины.

  3. Порядки P 1 ,…, P n образуют строго возрастающую последовательность смежных целых чисел.

Наконец, определим бесконечную цепочку гиперхинов как бесконечную последовательность полных программ или функций (P 1 , P 2 ,…), такую, что каждый начальный интервал (P 1 ,…, P n ) составляет цепочку гиперхин длины n .

Примеры

  • В гипотетическом языке программирования, где исходный код aabbccгенерирует выходные данные aaabbbccc, которые, в свою очередь, генерируют выходные данные aaaabbbbcccc, пара ( aabbcc, aaabbbccc) образует цепочку гиперхинов длиной 2 .

    Обратите внимание, что aaaabbbbcccc- вывод последней гиперхины в цепочке - не должен производить конкретный вывод; это даже не должен быть действительный исходный код.

  • Продолжая предыдущий пример, если aaaabbbbccccформирует выходной сигнал aaaaabbbbbccccc, триплет ( aabbcc, aaabbbccc, aaaabbbbcccc) представляет собой hyperquine цепь длиной 3 .

    Если эта картина продолжается вечно, последовательность ( aabbcc, aaabbbccc, aaaabbbbcccc...) представляет собой бесконечную цепь hyperquine.

  • Пара программ ( abc, aabbcc) с выходами ( aabbcc, aaaabbbbcccc) не является цепью гиперхина, поскольку порядки гиперхинов обе равны 1 , поэтому они не образуют строго возрастающую последовательность.

  • Пара программ ( aabbcc, aaaabbbbcccc) с выходами ( aaaabbbbcccc, aaaaabbbbbccccc) не является цепью гиперхин, поскольку порядки гиперхинов равны 1 и 4 , поэтому они не образуют последовательность смежных целых чисел.

правила

задача

На выбранном вами языке программирования напишите нетривиальную цепочку гиперхинов, т. Е. Цепочку, состоящую как минимум из двух гиперхинов.

Как обычно, ваши программы не могут вводить данные или получать доступ к своему исходному коду в любой форме.

Если ваш переводчик печатает неявную новую строку, ваши гиперхины должны учитывать это.

Применяются все стандартные лазейки, особенно те, которые связаны с куинами.

счет

Самая длинная цепь гиперхина побеждает. Если два или более представления связаны, то представление среди них, которое начинается с самой короткой гиперхины (измеряется символами ), выигрывает. Как обычно, время публикации является окончательным тай-брейком.


Вы должны использовать одинаковую кодировку символов для исходного кода, вывода, количества символов и выполнения. Например, программа Python print 42является не 2-символов UTF-32 представления, так как интерпретатор обрабатывает каждый байт как один символ. Если выбранный вами язык не основан на символах, обрабатывайте все отдельные байты как символы.

Деннис
источник
3
Хорошо, так что, возможно, вызов Хельки не был невозможным, но, конечно, это так: D
Beta Decay
1
@BetaDecay Это правда? :)
Мартин Эндер

Ответы:

10

Befunge-98 , бесконечный порядок, 54 52 38 36 байт

Второй подход - бесконечный порядок, 36 байтов

Эта программа фактически сломалась бы на 34-й гиперхине, так как значение ASCII "нарушило бы интерпретацию строки (и на 59, ;), но мы сместили хранение этого значения в позицию, которая никогда не будет выполнена (то есть (0, 1)вместо (0, 0)).

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

Попробуйте онлайн: 1 , 2 , 10 , 34 , 42

объяснение

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.

Первый подход - порядок 34, 52 байта (использует самоанализ, поэтому технически не легален)

По причине, описанной в приведенном выше посте, эта программа будет работать с ошибкой 34 (хотя я не проверял).

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

Попробуйте онлайн!

Hactar
источник
2
Хотя вывод выглядит правильным, и это, безусловно, впечатляет, я не уверен, что можно использовать правильный quine g, который, кажется, непосредственно читает исходный код программы. Тем не менее, я вряд ли эксперт Befunge, поэтому я могу что-то неправильно понять.
Деннис
Я использую gздесь две цели: хранить данные и читать исходный код. Второй может быть немного отрывочным, хотя у esolangs.org/wiki/Befunge#Quine есть пример, использующийся gдля чтения исходного кода. А пока я посмотрю, смогу ли я создать версию, которая не использует самоанализ.
Гактар
Я знал, что это должно быть возможно в Befunge, но я понятия не имел, как. Спасибо, что показали мне. +1
ETHproductions
10

> <> , бесконечный порядок, 178 байт

Программа содержит завершающий перевод строки.

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

Попробуйте онлайн: 1 , 2 , 3 , 10 (для запуска последнего требуется время.)

Retina скрипт для генерации исходного кода из линейной программы.

объяснение

Основная идея состоит в том, чтобы повернуть куину по вертикали, чтобы повторение не влияло на реальный поток управления. Например, второй гиперхайн начинается так:

^^

..

**

Поскольку мы перемещаемся только через первый столбец, нам не нужно беспокоиться о повторяющихся символах. Кроме того, когда мы помещаем большую часть кода в строку ', это приводит к появлению пробела для каждой пустой строки, что дает нам возможность определить количество повторений. Тем не менее, есть некоторые ограничения из-за этих пустых строк:

  • Мы не можем использовать "нажатие больших чисел в качестве кодов символов в основной части квин, потому что это приведет к добавлению дополнительных 32s, которые нам не нужны.
  • Мы не можем использовать ?или !потому, что они пропускают только следующий символ, который в этом случае будет пробелом (так что они фактически не будут пропускать следующую команду).

Следовательно, весь поток управления выполняется с явными переходами (в основном, 2D-переход), чьи фактические смещения нам нужно рассчитывать на основе количества повторений.

Итак, давайте посмотрим на реальный код. Начнем с ^того, что код выполняется снизу вверх. Для удобства чтения давайте выпишем реальный код в порядке выполнения (и отбросим его, ^потому что он никогда не выполняется снова):

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

Это 'стандартная техника квинтинга для> <> (и, наверное, Befunge). Он переключается в строковый режим, что означает, что встречающиеся символы помещаются в стек, пока не встретятся следующие '. Пустые строки неявно дополняются пробелами, поэтому мы получаем все пробелы между ними. Пустые строки в конце программы игнорируются. Таким образом, после того, как IP обернулся и ударил 'снова, у нас есть первый столбец программы в стеке, за исключением 'самого.

Давайте посмотрим, как мы используем это для печати всей программы.

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.

Программа завершается, когда стек пуст и первый внутренний цикл не может распечатать другой символ.

Мартин Эндер
источник