Nas aventuras anteriores da série de blogs Quine, exploramos como escrever nossos próprios Quines e Introns. Hoje veremos o que são QuineRelays e como você pode aproveitar Introns para criá-los.
Imagine um círculo de programas, cada um escrito em uma linguagem diferente. Cada programa neste círculo tem um único propósito: imprimir o código-fonte do próximo programa da sequência. O último programa fecha o loop imprimindo o código-fonte do primeiro programa.
Essencialmente, QuineRelays são um conjunto de n programas, em n linguagens diferentes, tais como:
Vamos ver alguns exemplos para entender melhor o conceito.
Este QuineRelay de 2ª ordem apresenta um programa JavaScript que imprime um programa Python, que então imprime o programa JavaScript original de volta. É uma dupla dinâmica de auto-replicação.
JavaScript → Python ⥀
JavaScript: experimente on-line!
console.log((q=_=>`print(${JSON.stringify(`console.log((q=${q []})())`)})`)())
Python: experimente on-line!
print("console.log((q=_=>`print(${JSON.stringify(`console.log((q=${q []})())`)})`)())")
As coisas ficam ainda mais interessantes com um QuineRelay de 3ª ordem. Este começa com um programa Haskell, que gera um programa Python, que gera um programa Ruby e, finalmente, o programa Ruby retorna ao programa Haskell original.
Haskell → Python2 → Ruby ⥀
Haskell: Experimente online!
q a b c=putStrLn $ b [toEnum 10,'q','('] show b [','] show c [','] show a [')'] main=q "q a b c=putStrLn $ b [toEnum 10,'q','('] show b [','] show c [','] show a [')']" "def q(a,b,c):print b chr(10) 'q(' repr(b) ',' repr(c) ',' repr(a) ')'" "def e(x) return 34.chr x 34.chr end;def q(a,b,c) print b 10.chr 'main=q ' e(b) ' ' e(c) ' ' e(a) ' ' 10.chr end"
Python2: experimente on-line!
def q(a,b,c):print b chr(10) 'q(' repr(b) ',' repr(c) ',' repr(a) ')' q("def q(a,b,c):print b chr(10) 'q(' repr(b) ',' repr(c) ',' repr(a) ')'","def e(x) return 34.chr x 34.chr end;def q(a,b,c) print b 10.chr 'main=q ' e(b) ' ' e(c) ' ' e(a) ' ' 10.chr end","q a b c=putStrLn $ b [toEnum 10,'q','('] show b [','] show c [','] show a [')']")
Ruby: Experimente online!
def e(x) return 34.chr x 34.chr end;def q(a,b,c) print b 10.chr 'main=q ' e(b) ' ' e(c) ' ' e(a) ' ' 10.chr end q("def e(x) return 34.chr x 34.chr end;def q(a,b,c) print b 10.chr 'main=q ' e(b) ' ' e(c) ' ' e(a) ' ' 10.chr end","q a b c=putStrLn $ b [toEnum 10,'q','('] show b [','] show c [','] show a [')']","def q(a,b,c):print b chr(10) 'q(' repr(b) ',' repr(c) ',' repr(a) ')'")
Aqui está um QuineRelay de 4ª ordem: Ruby → Java → C# → Python ⥀
GitHub
Em todas as culturas, existem vários simbolismos compartilhados. Um deles é o Ouroboros, que tem referências nas mitologias egípcia, grega, romana, hindu, siberiana, nórdica, africana e sul-americana. O Ouroboros é um símbolo antigo que representa uma serpente ou dragão consumindo sua própria cauda, representando o ciclo eterno de criação e destruição.
Os relésNa mitologia nórdica, Jörmungandr é uma serpente colossal, o filho do meio de Loki e da giganta Angrboða. Odin lançou Jörmungandr no oceano que cerca Midgard (o reino dos humanos), onde a serpente cresceu tão imensa que circundou o mundo e agarrou sua própria cauda. Como resultado de cercar Midgard (a Terra), ela é conhecida como a Serpente Mundial - Ouroboros. Jörmungandr soltando a cauda é um dos sinais do início do Ragnarök (a batalha final do mundo).
Quine incorporam esse simbolismo de maneira bastante clara, pois cada programa no ciclo dá origem ao próximo, apenas para renascer no final e, portanto, são apelidados de programas Ouroboros.
Segurem-se em seus lugares. Aqui está um Ouroboros QuineRelay de 128ª ordem. Sim, você leu certo. 128!!!
Ruby → Rust → Scala → ... (120 outros) ... → Python → R → Ratfor → rc → REXX ⥀
GitHub
Como se isso não fosse impressionante o suficiente, inclui um ovo de páscoa. O código Ruby original quando reduzido contém um dragão Ouroboros!
Vamos iniciar o íntron Python que escrevemos anteriormente e tentar transformá-lo em um QuineRelay de 2ª ordem.
Python Intron: experimente online!
intron = 'wubbalubbadubdub' data = "print('intron =', repr(intron)); print('data =', repr(data)); print(data)" print('intron =', repr(intron)); print('data =', repr(data)); print(data)
Usando a magia dos íntrons, agora podemos facilmente colocar a parte código de um irmão Quine de uma linguagem diferente no íntron. Produzindo um programa no formato:
Python:
intron = "code part of sibling" data = "code part of self" print('intron =', repr(intron)); print('data =', repr(data)); print(data)
Já que cada variável é apenas, agindo como dados de um Quine diferente. Vamos renomear data e intron para d1 e d2 respectivamente.
Python:
d1 = "code part of self" d2 = "code part of sibling" print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d1)
Agora, d2 atua como um íntron, mas o programa acima ainda tentou imprimir parte do código de si mesmo. Para que ele imprima a fonte do próximo, vamos print(d2) em vez de print(d1) no final.
Python:
d1 = "code part of self" d2 = "code part of sibling" print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)
Já sabemos que o conteúdo de d1 é apenas uma cópia da linha 3. Mas ainda não temos o conteúdo de d2.
Digamos, queríamos criar um QuineRelay com JavaScript. Vamos escrever um intron semelhante em JS.
JavaScript:
d1 = "code part of sibling" d2 = "code part of self" console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1);
Agora, a linha 3 do intron JS acima, é o código do programa irmão que queríamos!
Cole o código um do outro como íntrons no outro.
Observação. Precisamos adicionar d1 '' em js para evitar algumas incompatibilidades de cotação
Python: experimente on-line!
d1 = "print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)" d2 = "console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 '');" print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)
JavaScript: experimente on-line!
d1 = "print('d1 =', repr(d1)); print('d2 =', repr(d2)); print(d2)" d2 = "console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 '');" console.log(`d1 = ${JSON.stringify(d1)}`); console.log(`d2 = ${JSON.stringify(d2)}`); console.log(d1 '');
Aí está. É um QuineRelay de 2ª ordem adequado! Um programa Python, que imprime um programa JavaScript, que imprime o programa Python original em um ciclo.
Criar um QuineRelay é um exercício de codificação criativa e compreensão de como diferentes linguagens representam e manipulam strings. Envolve unir íntrons de vários programas, cada um contendo o código para replicar seu próximo vizinho.
Em sua essência, um relé de enésima ordem é um jogo de n maneiras inteligentes de escapar de aspas em n linguagens de programação.
Fique ligado na próxima postagem no MultiQuine!
Fontes e referências:
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3