O desafio
Neste desafio, você especifica um idioma de origem S
e um idioma de destino T
. Sua tarefa é escrever o seguinte programa P
no idioma S
. Se um programa válido Q
no idioma T
for fornecido como entrada P
, ele produzirá um programa válido R
no idioma T
que não recebe entradas e saídas Q(R)
, ou seja, o programa Q
aplicado ao código fonte de R
. Além disso , você deve apresentar em sua resposta um programa de exemplo não trivial Q
(quanto mais interessante, melhor, embora você não marque pontos), o programa resultante R
e a saída de R
. Este é o código-golfe, então o código mais curto para P
vitórias.
Em outras palavras, esse é um desafio sobre escrever um "construtor universal de quine" que possa criar tipos arbitrários de quines generalizados.
Esclarecimentos
- Seus idiomas de origem e destino podem ser idênticos.
- O programa
P
deve pegar uma string como entrada (de STDIN ou equivalente) e gerar uma string (para STDOUT ou equivalente), como todos os programas de saídaR
. - Os programas de entrada
Q
também devem transformar uma sequência em outra, mas sua forma é mais flexível: eles podem ser funções de sequência a sequência, trechos de código que modificam uma variável com um determinado nome, trechos que modificam a pilha de dados se o idioma de destino você também pode restringir ainda mais a forma dosQ
, afirmando que, por exemplo, eles podem não conter comentários. No entanto, você deve poder implementar qualquer função cadeia a cadeia computável como um programa de entradaQ
e deve declarar explicitamente como eles funcionam e quais restrições adicionais você impõe a eles. - O programa de saída
R
deve realmente ser um quine (generalizado), portanto, não deve ler nenhuma entrada (entrada do usuário, arquivos etc.), a menos que oQ
faça. - As brechas padrão não são permitidas.
Um exemplo
Suponha que eu escolha Python como idioma de origem e Haskell como idioma de destino, além de exigir que o programa de entrada seja uma definição de uma linha de uma String -> String
função denominada f
. Se eu der o programa de reversão de string
f x = reverse x
como entrada para o meu programa Python P
, ele produzirá o código fonte de outro programa Haskell R
. Este programa imprime em STDOUT o código fonte R
, mas invertido. Se P
for dada a função de identidade
f x = x
como entrada, o programa de saída R
é um quine.
fonte
Expressões haskell → Expressões haskell, 41 bytes
Experimente online!
Como funciona
P $ "Q"
=((++)<*>show).('(':).(++")$(++)<*>show$") $ "Q"
constrói"R"
por(++")$(++)<*>show$")
: anexando a string")$(++)<*>show$"
,('(':)
: anexando o caractere'('
e(++)<*>show
(=\x->x++show x
): anexando uma versão citada disso,resultando em
"R"
="(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""
.R
=(Q)$(++)<*>show$"(Q)$(++)<*>show$"
trabalha por"(Q)$(++)<*>show$"
,(++)<*>show
: anexando uma versão citada disso,Q
a isso,resultando em
Q "(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""
=Q "R"
.(Os parâmetros
Q
são necessários porqueQ
podem conter$
tão facilmente quanto oR
fazem e,$
infelizmente, são associativos.)Demo
fonte
$
precisa dos parênteses, mas também à direitalet
,do
ou expressões lambda.let
/if
/case
/do
se eu não os emitir. Talvez seja tão bom que eu não precisei.Fonte = Destino = JavaScript, 66
Pressupostos para Q:
Q
deve ser uma função anônima JavaScript string a string.Exemplos:
function(s) { return s.split('').reverse().join(''); }
Nesse caso,
P(Q)
(ouR
) será:function a(){console.log(function(s) { return s.split('').reverse().join(''); }(a+'a()'))}a()
e, executando-o, obteremos:)(a}))')(a'+a(} ;)''(nioj.)(esrever.)''(tilps.s nruter { )s(noitcnuf(gol.elosnoc{)(a noitcnuf
que é exatamente o mesmo queQ(R)
.function(s) { return s; }
nesse caso,
P(Q)
(ouR
) será:function a(){console.log(function(s) { return s; }(a+'a()'))}a()
que é um JavaScript Quine . Escusado será dizerQ(R)
que será o mesmo, pois Q é a função de identidade.Algumas notas:
STDIN em JavaScript é tradicionalmente
prompt()
, no entanto, eu me permiti abster-me da tradição dealert()
STDOUT, a fim de facilitar o processo de execução da saída como um programa usando copiar e colar. (Percebo que posso salvar até 12 caracteres ao mudar paraalert()
).Também posso tornar as coisas muito mais curtas no ES6, mas quero continuar com o JavaScript nativo por enquanto. Estou pensando em enviar uma resposta S = Scala, T = ECMA6 no futuro, apenas para a experiência.
Também sei que o JavaScript quase nunca consegue vencer o CJam no código-golfe , mas tive que aceitar esse desafio! Foi grosseiramente divertido.
fonte
Geléia → 7 , 9 bytes
Experimente online!
Q é uma função 7 (ou seja, que não olha para além do elemento superior da pilha e faz E / S via pilha) e é fornecida como um argumento da linha de comando.
Explicação
O programa 7
O construtor universal de quine em 7 que eu uso aqui é:
A primeira coisa a se notar é que o 7 inicial é o equivalente ao espaço em branco inicial e não afeta o programa. A única razão para existir é obedecer às regras do PPCG contra quines somente literais (é codificado pelo segundo
1
no programa e não por ele próprio).O resto do programa é um único elemento pilha (ela tem equilibrado
7
s e6
s), que faz o seguinte quando executado:Em outras palavras, esse elemento da pilha é um programa que imprime a parte superior da pilha, com o
7
formato de saída 7 anexado (que significa "imprimir literalmente, usando a mesma codificação que o código-fonte") e, portanto, é claramente a melhor codificação para quines). É bastante sorte aqui podermos reutilizar o literal7
para dois propósitos (o formato de saída e o espaço em branco à esquerda). Claramente, inserindo algo logo antes da final3
, podemos gerar uma função de7
+ a entrada, em vez de apenas produzir7
e entrada diretamente.Como esse elemento de pilha obtém seu próprio código-fonte? Bem, quando o final do programa é alcançado, 7
eval
é o elemento da pilha superior por padrão. No entanto, ele não é realmente retirado da pilha no processo, portanto o literal do elemento da pilha que foieval
conduzido ainda está lá. (Em outras palavras, o programa não está lendo sua própria fonte - como evidenciado pelo fato de não poder ver o7
arquivo no início do programa, que é um separador de elementos da pilha e não parte de um literal - mas sim consiste principalmente de um literal que éeval
liderado por padrão.)O programa Jelly
Este é talvez um dos programas Jelly menos parecidos com o que eu já escrevi; ele é composto por três nilads (
“ṚƓ^ṾṂ’
,³
,3
), que são emitidos apenas em sequência porque não há operações são realizadas em cima delas. O3
é bastante óbvio, apenas sendo uma constante inteira. A³
também é simples se você sabe Jelly: é notação explícita de geléia para o primeiro argumento de linha de comando (que é onde Jelly normalmente leva sua entrada). O restante do programa Jelly representa a maior parte do meu construtor universal de 7 quine: explorando o fato de que todos os comandos no 7 podem ser representados usando dígitos ASCII, podemos interpretar717162234430
não como uma série de comandos, ou mesmo como um número octal (como é conceitualmente), mas como um número decimal, o que significa que não precisamos de nenhuma formatação especial para a saída. Esse número decimal se torna“ṚƓ^ṾṂ’
na notação inteira comprimida de Jelly.Exemplo
Se dermos
24053
como programa Q, obteremos a seguinte saída:Experimente online!
2405
concatena o elemento da pilha superior para si mesmo:(A última etapa pode parecer um pouco confusa; o que está acontecendo é que escapar de um elemento da pilha converte cada comando nele de "execute este comando" para "anexar esse comando ao topo da pilha", de modo que cada comando se anexa ao original elemento da pilha superior à medida que é executado.)
Como tal, a execução do programa resultante R fornece duas cópias de R:
fonte
CJam → CJam, 13 bytes
Experimente online!
A entrada
Q
deve ser um trecho de código que modifica a única sequência na pilha.Q
é lido de stdin.Exemplo
Entrada:
Ele adiciona um espaço entre cada dois caracteres e inverte a string.
Resultado:
Saída da solução generalizada:
Explicação
Primeiro, ele avalia o quine, para que possamos obter sua representação de string sem aspas duplas desnecessárias. Em seguida, substitua a carga útil pela entrada.
Pode ser
{`"_~"+ }_~7qt
onde o espaço é o espaço reservado para a carga útil. Mas alterar a carga útil para7
economizar um byte.fonte
Carvão → Perl (5),
2933 bytesExperimente online!
O programa Perl Q deve retornar um trecho que leva a entrada como uma string para o lado direito e fornece saída na variável
$_
. (As funções arbitrárias de Perl podem ser convertidas para esse formulário, agrupando-as comosub x {…}; $_=x
. Na maioria dos casos, porém, a sintaxe de Perl significa que nenhuma quebra é necessária.)Explicação
The Perl
Aqui está a aparência do construtor universal Perl quine:
(Na maioria dos casos, você gostaria disso
$_=q(say…"\$_=q($_);eval");eval
, mas não tenho certeza de que você pode inserir um código Perl arbitrário…
nele).Em outras palavras, temos um invólucro externo
$_=q(…);eval
que atribui uma string$_
e a avalia. Dentro do invólucro está"\$_=q($_);eval"
, ou seja, uma reconstrução do invólucro junto com seu conteúdo, usando o valor armazenado$_
, mais o código Q especificado pelo usuário, maisprint
para imprimir a saída. (Infelizmente, não podemos usá-say
lo; ele adiciona uma nova linha, e isso é relevante em quines.)O carvão
O "ponto" desta resposta era produzir quines generalizadas em Perl, então, quando eu tive uma estratégia de golfe para fazer isso (uma que eu já usei em muitas outras respostas), era hora de escrever o programa P, que basicamente substitui uma string em um modelo. O que eu queria aqui era uma linguagem que fosse boa para imprimir seqüências constantes (idealmente comprimindo-as um pouco) e interpolar a entrada do usuário nelas.
Depois de experimentar alguns, decidi pelo carvão vegetal, que nunca havia usado antes (e que poderia realmente fazer com alguma documentação); Ele foi projetado para a arte ASCII, mas também é capaz de escrever strings em uma dimensão. Os caracteres ASCII são impressos literalmente em carvão vegetal, o que significa que a impressão de seqüências constantes não requer clichê, e podemos usar o
S
comando para interpolar uma sequência retirada da entrada do usuário no programa.É possível ir (um pouco) mais curto, no entanto. O construtor de quine universal Perl contém duas seções repetidas bastante longas. Assim, podemos usar o
A
comando para atribuí-los a variáveis (por exemplo,A…α
atribui à variávelα
) e simplesmente interpolar as variáveis na string que estamos imprimindo usando seus nomes. Isso economiza alguns bytes ao escrever apenas a string literalmente.Infelizmente, o Charcoal também acrescenta uma nova linha ao programa, mas isso não é grande coisa; simplesmente custa dois bytes para que um
\n
adicione essa nova linha à entrada de Q também.Exemplo
Se dermos a entrada
$_=reverse
(que inverte uma string), obtemos a seguinte saída:Experimente online!
que é semelhante a um quine que imprime sua fonte para trás, como esperado.
fonte
Geléia → Subcarga , 15 bytes
Experimente online!
Pega a função Underload de entrada Q como um argumento semelhante a um comando. O Q deve receber a entrada da pilha e enviar a saída para a pilha, sem tentar inspecionar elementos mais profundos da pilha (pois eles não existirão).
Explicação
The Underload
O construtor de quino universal Underload usado aqui é:
A maior parte do programa é um único literal. Seguimos que
:^
, que copia e avalia uma cópia (deixando a outra cópia na pilha).Quando o literal começa a avaliar, executamos
a
(escape, que o traz de volta à mesma forma que o programa original A) e(:^)*
(que acrescenta:^
), reconstruindo assim o código fonte do programa inteiro. Podemos então executar a função Q para transformar isso de maneira arbitrária e imprimir o resultado comS
.The Jelly
Não posso usar o Charcoal neste momento porque um intérprete de Underload validador falha no final do programa se o programa terminar com uma nova linha. (Alguns intérpretes do Underload, como o do TIO, não impõem essa regra, mas eu queria ser adequadamente portátil.) Infelizmente, o Charcoal naturalmente adiciona novas linhas à saída. Em vez disso, usei o Jelly, que é quase tão conciso em casos simples como esse; o programa consiste em uma lista literal com dois elementos (
““”
) e os une à entrada (j
), interpolando assim a entrada do usuário no programa.Exemplo
Usando a entrada
:S^
(imprima uma cópia e avalie o original), obtemos o seguinte programa Underload:Experimente online!
Isso se imprime infinitamente várias vezes, de uma maneira bastante interessante: depois de executar o comportamento normal do quine, ele é executado
eval
em uma cópia do que sai . Isso faz com que todo o programa reconstruído seja executado novamente indefinidamente (Underload é recursivo da cauda). Fazer a si mesmo e fazer umeval
é realmente a única maneira de fazer um loop infinito no Underload.fonte
RProgN 2 , 11 bytes
Explicação do Programa
Explicação Quine
O quine produzido é simples, mas usa a funcionalidade de manipuladores de funções incomparáveis no RProgN2 para criar um quine curto e agradável, chamado quine "Looping". É um conceito surpreendentemente semelhante a um <> <quine.
Obviamente, devido à estrutura desse quine, qualquer coisa, exceto as verdadeiras no-ops (que não são rigorosas) pode ser colocada após a função concatenada, e
Algumas quines
{`{.i}{
: Saídas{}i.{`{
.i
é apenas a função "inversa"; portanto, este programa gera uma saída invertida.{`{.S§.}{
: Saídas..S`{{{}§
.S
converte a sequência em uma pilha de caracteres,§
classifica a pilha lexograficamente e, em seguida,.
junta-a novamente, produzindo-se classificada.Experimente online!
fonte