Hiper sobre quines


27

Inspirado pela hiperprogramação: N + N, N × N, N ^ N, tudo em um .
Agradecemos a @MartinEnder e @trichoplax por sua ajuda na sandbox.

Definições

Hyperquines

Defina uma hiperquina de ordem n como um programa completo ou função P semelhante a uma solução que satisfaça todas as regras que se aplicam a soluções adequadas e, além disso, possui a seguinte estrutura.

P é a concatenação de caracteres grupos que consistem de n cópias da mesma natureza. Quando P é executado, a saída é a concatenação dos mesmos grupos, aumentada por mais uma cópia do caractere.

Exemplos

  • Em uma linguagem de programação hipotética em que o código fonte aabbccgera a saída aaabbbccc, este programa constitui uma hiperquina de ordem 2 .

  • A definição não requer que os caracteres de grupos diferentes sejam diferentes.

    Se o código fonte aabbccgerar a saída aaaabbbbcccc, o programa é uma hiperquina da ordem 1 ; o código fonte consiste em seis grupos de caracteres únicos, a saída de seis pares de caracteres.

  • No GS2 , o programa vazio é impresso \ne o programa é \nimpresso \n\n. No entanto, \nnem \n\nsão nem hiperquinas, pois não satisfazem todas as propriedades de quines apropriadas ; nenhuma parte do código-fonte codifica uma parte diferente da saída.

Cadeias de hiperquinas

Defina uma cadeia hiperquina de comprimento n como uma sequência finita de n programas completos ou n funções
(P 1 ,…, P n ) que atenda às seguintes restrições.

  1. As saídas de P 1 ,…, P n-1 são P 2 ,…, P n , respectivamente.

  2. P 1 ,…, P n são hiperquinas.

  3. As ordens de P 1 ,…, P n formam uma sequência estritamente crescente de números inteiros adjacentes .

Finalmente, definir uma cadeia hyperquine infinito como uma sequência infinita de programas completos ou funções (P 1 , P 2 , ...) de tal modo que cada intervalo inicial (P 1 , ..., P n ) constitui uma cadeia de comprimento hyperquine n .

Exemplos

  • Em uma linguagem de programação hipotética em que o código fonte aabbccgera a saída aaabbbccc, que por sua vez gera a saída aaaabbbbcccc, o par ( aabbcc, aaabbbccc) constitui uma cadeia hiperquina de comprimento 2 .

    Observe que aaaabbbbcccc- a saída da última hiperquina na cadeia - não precisa produzir uma saída específica; nem precisa ser um código fonte válido.

  • Continuando com o exemplo anterior, se aaaabbbbccccgera a saída aaaaabbbbbccccc, o tripleto ( aabbcc, aaabbbccc, aaaabbbbcccc) constitui uma cadeia de comprimento hyperquine 3 .

    Se esse padrão continuar para sempre, a seqüência ( aabbcc, aaabbbccc, aaaabbbbcccc, ...) constitui uma cadeia hyperquine infinito.

  • O par de programas ( abc, aabbcc) com saídas ( aabbcc, aaaabbbbcccc) não é uma cadeia hiperquina, uma vez que as ordens das hiperquinas são ambas 1 , portanto, elas não formam uma sequência estritamente crescente.

  • O par de programas ( aabbcc, aaaabbbbcccc) com saídas ( aaaabbbbcccc, aaaaabbbbbccccc) não é uma cadeia hiperquina, uma vez que as ordens das hiperquinas são 1 e 4 , portanto, elas não formam uma sequência de números inteiros adjacentes.

Regras

Tarefa

Em uma linguagem de programação de sua escolha, escreva uma cadeia de hiperquinas não trivial, ou seja, uma cadeia que consiste em pelo menos 2 hiperquinas.

Como de costume, seus programas não podem receber nenhuma entrada ou acessar seu próprio código-fonte de qualquer forma.

Se o seu intérprete imprime uma nova linha implícita, suas hiperquinas precisam ser responsáveis ​​por isso.

Todas as brechas padrão - especialmente aquelas relacionadas a quines - se aplicam.

Pontuação

A maior cadeia de hiperquinas vence. Se duas ou mais submissões estiverem vinculadas, a submissão entre essas que começa com a hiperquina mais curta (medida em caracteres ) vence. Como sempre, o tempo de postagem é o desempate final.


Você deve usar a mesma codificação de caracteres para código fonte, saída, contagem de caracteres e execução. Por exemplo, o programa Python nãoprint 42 é um envio UTF-32 de 2 caracteres, pois o intérprete trata cada byte como um único caractere. Se o seu idioma de escolha não for baseado em caracteres, trate todos os bytes individuais como caracteres.


3
Ok, talvez o desafio de Helka não tenha sido impossível, mas com certeza é o seguinte: D
Beta Decay

1
@BetaDecay É mesmo? :)
Martin Ender

Respostas:


10

Befunge-98 , ordem infinita, 54 52 38 36 bytes

Segunda abordagem - ordem infinita, 36 bytes

Na verdade, esse programa seria interrompido na 34ª hiperquina, pois o valor ASCII de "interromperia a interpretação das strings (e 59 ;), mas compensamos o armazenamento desse valor em uma posição que nunca será executada (por exemplo, em (0, 1)vez de (0, 0)).

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

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

Explicação

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.

Primeira abordagem - encomende 34, 52 bytes (usa introspecção, portanto tecnicamente não é legal)

Pela razão no post acima, este programa seria quebrado na ordem 34 (embora eu não tenha testado).

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

Experimente online!


2
Embora a saída pareça estar correta e isso seja certamente impressionante, não estou convencido de que uma solução adequada possa ser usada g, o que parece ler diretamente o código-fonte do programa. Dito isto, dificilmente sou um especialista em Befunge, por isso posso estar entendendo mal alguma coisa.
Dennis

Estou usando gpara dois propósitos aqui: armazenar dados e ler o código fonte. O segundo pode ser um pouco superficial, embora esolangs.org/wiki/Befunge#Quine tenha um exemplo usando gpara ler também o código-fonte. Enquanto isso, vou ver se consigo criar uma versão que não use nenhuma introspecção.
Hactar 07/10

Eu sabia que isso deveria ser possível em Befunge, mas não fazia ideia de como. Obrigado por me mostrar. +1
ETHproductions

10

> <> , ordem infinita, 178 bytes

O programa contém um avanço de linha à direita.

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

Experimente online: 1 , 2 , 3 , 10 (Esse último demora um pouco para ser executado.)

Script de retina para gerar fonte do programa linear.

Explicação

A idéia principal é tornar o quine vertical, para que o fluxo de controle real não seja afetado pela repetição. Por exemplo, o segundo hiperquino começa como:

^^

..

**

Como estamos apenas passando pela primeira coluna, não precisamos nos preocupar com caracteres repetidos. Além disso, quando pressionamos a maioria do código como uma string ', isso abre um espaço para cada linha vazia, o que nos permite determinar o número de repetições. Dito isto, existem algumas limitações devido a estas linhas vazias:

  • Não podemos usar "números grandes como códigos de caracteres na parte principal do quine, porque isso gera 32s adicionais que não queremos.
  • Não podemos usar ?ou !porque eles pulam apenas o próximo caractere, que seria um espaço nesse caso (para que eles não pulem o próximo comando).

Portanto, todo o fluxo de controle é feito com saltos explícitos (2D em goto, basicamente), cujas compensações reais precisamos calcular com base no número de repetições.

Então, vamos olhar o código real. Começamos com ^para que o código seja executado de baixo para cima. Para facilitar a leitura, vamos escrever o código real em ordem de execução (e soltar o código ^porque ele nunca é executado novamente):

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

Essa 'é a técnica padrão de quining para> <> (e Befunge, eu acho). Ele muda para o modo de sequência, o que significa que os caracteres encontrados são empurrados para a pilha até que o próximo 'seja encontrado. Linhas vazias são preenchidas implicitamente com espaços e é por isso que temos todos os espaços intermediários. Linhas vazias no final do programa são ignoradas. Então, depois que o IP envolve e atinge o 'novo, temos a primeira coluna do programa na pilha, exceto a 'própria.

Vamos ver como usamos isso para imprimir o programa inteiro.

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.

O programa termina quando a pilha está vazia e o primeiro loop interno falha ao imprimir outro caractere.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.