Imprimir peças poliglotas

22

Normalmente, os poliglotas são construídos de tal maneira que cada idioma pode ignorar partes do código que estão presentes em outros idiomas, envolvendo-os em literais de string, usando sintaxe de comentário ou outros truques semelhantes.

Seu objetivo é escrever uma poliglota em que a saída para cada idioma seja o código da poliglota que produz essa saída. Especificamente, a saída deve ser construída a partir do código poliglota apenas com exclusões e deve ser uma solução no idioma especificado.

Regras

  • Somente quines apropriados são permitidos (sem leitura do código fonte, sem entrada de entrada, a saída deve ser STDOUT ou a alternativa mais próxima se STDOUT não for uma opção e os programas devem consistir em mais do que apenas literais que são impressos implicitamente).
  • Como idiomas diferentes podem usar codificações diferentes, os bytes brutos são o que importa aqui. Por exemplo, se o idioma A usar UTF-8 e o idioma B usar CP437, o código (hex) C3 88 46 47será ÈFGpara o idioma A e ├êFGpara o idioma B.
  • Todas as saídas devem ser distintas (novamente, comparando bytes brutos). Isso evita complicações com a tentativa de restringir versões de idiomas menores - se dois idiomas usam a mesma parte do código para fazer a mesma coisa, você não pode reivindicar os dois.
    • Se você tiver dois idiomas A e B, que XYsejam uma saída válida em ambos, mas YZtambém seja válido em B, poderá escolher XYcomo saída para A e YZcomo saída para B, para poder reivindicar os dois em sua pontuação ( mas você não pode reivindicar os XYdois idiomas por causa da regra acima).
  • Todas as saídas devem ser tão curtas quanto possível. Por exemplo, se seu código fosse print('foo')#something, para Python 3 (ignorando o fato de que a saída não está correta), o código que você precisaria produzir seria print('foo')e print('foo')#não seria permitido. Se houver várias cadeias de comprimento igual (mínimo) que produzam a saída correta, você pode escolher qualquer uma delas.
  • As inscrições devem ser poliglotas em pelo menos 2 idiomas.
  • Sua pontuação será dada por (number of programming languages with distinct outputs)**3/(total byte size of polyglot). A pontuação mais alta vence. No caso de duas submissões atingirem a mesma pontuação, a submissão que atingir essa pontuação primeiro vencerá.
Mego
fonte
2
A penúltima regra parece que precisamos provar que é impossível jogar o quine resultante ainda mais com qualquer outro conjunto possível de exclusões. Isso é intencional?
Martin Ender
Relacionado.
Martin Ender
Como você define "exclusões" no caso de um idioma cujos comandos não têm 8 bits de comprimento? Você exclui da fonte um comando por vez ou um byte por vez?
@MartinEnder Boa fé pode ser assumida. A menos que alguém encontre um quine mais curto que possa ser formado a partir da poliglota, a resposta é confiável para ser válida.
Mego
@ ais523 Tudo é feito no nível de bytes.
Mego

Respostas:

11

GolfScript + CJam + Fissão 2 + Geléia , 4 idiomas, 24 bytes, pontuação 2.667

Vamos começar com o hex dump:

00000000:  3322 3024 700a 2721 2b4f 5222 0a3c 3024 700a 6523 7fff cccc

Para GolfScript, CJam e Fission 2, interpretamos isso em alguma codificação de byte único compatível com ASCII, como ISO 8859-1 (a codificação exata não importa, porque as linguagens definem os operadores apenas para caracteres ASCII):

3"0$p
'!+OR"
<0$p
e#<DEL>ÿÌÌ

Onde <DEL>está o caractere de controle 0x7f.

No Jelly, supõe-se que isso esteja na página de código do próprio Jelly, onde fica assim:

3"0$p½'!+OR"½<0$p½e#¶”ṘṘ

GolfScript

A eúltima linha é uma variável desconhecida e #comenta o restante da linha, portanto, isso imprime

"0$p"
0$p

com um avanço de linha à direita. Esta é a versão poliglota GolfScript / CJam do quine padrão:

".p"
.p

Experimente o poliglota. | Experimente o quine.

CJam

Aqui, e#comenta a última linha, de forma quase idêntica, isso imprime

"0$p"
0$p

sem avanço de linha à direita.

Experimente o poliglota | Experimente o quine.

Fissão

A fissão vê apenas a segunda linha, que é o padrão de fissão, portanto imprime

'!+OR"

Não posso fornecer um link online para o poliglota aqui, porque o TIO envia o arquivo para Fission como UTF-8, mas o Fission lê o byte de origem a byte, o que torna a última linha muito longa. No entanto, testei isso localmente com um arquivo codificado ISO 8859-1 (no qual a última linha tem o mesmo comprimento que a segunda), para confirmar que isso funciona.

Experimente o quine.

Geléia

O pilcrow é um alias para feeds de linha no Jelly, portanto, a fonte é equivalente a:

3"0$p½'!+OR"½<0$p½e#
”ṘṘ

Todos, exceto a última linha de um programa Jelly, são "links auxiliares" (ou seja, funções) que podem ser ignorados a menos que sejam chamados, desde que sejam sintaticamente válidos. Esta é realmente a razão pela qual o 3primeiro vem nos programas CJam e GolfScript, porque, caso contrário, "não poderá ser analisado no Jelly.

Caso contrário, como a função não é chamada, o programa é equivalente a apenas sua segunda linha, que é o padrão Jelly Quine.

Experimente o poliglota. | Experimente o quine.

Martin Ender
fonte
9

> <> + Python, 2 idiomas, 51 46 bytes, pontuação ~ = 0,16 0,17

Como ainda não há respostas, começarei com uma simples

#.09;!?lo}*2+2f"
_='_=%r;print _%%_';print _%_

Experimente para > <> e Python

Para> <> a primeira linha é um quine (# reflete ", coloca a linha inteira na pilha, pressionamos 34 (código para") e imprimimos tudo), a execução nunca sai dela, portanto ignora efetivamente o restante o código.

Para Python, a primeira linha é um comentário, enquanto a segunda é uma quine (abordagem padrão em python, usando substituição de string com a mesma string dos dois argumentos).

Leo
fonte
1
Adaptação ligeira no> <> resposta pode poupar alguns bytes: -?! # "~ R10gol; 60. |
Teal pelicano
@Tealpelican Obrigado por me lembrar do uso de .! Eu adaptei meu quine usando essa abordagem, apesar de preferir manter a string em sentido inverso (pois isso economiza bytes) e evitar o uso g(já que ela pode ser interpretada como "lendo o código-fonte")
Leo
Esse é um ponto bastante justo para não usar g. Observando e pensando um pouco, é possível reduzi-lo ainda mais usando o # (ascii 35) da pilha para obter o "like; # .09;!? Lo} -1"
Teal pelican
7

JavaScript + Python 2 + Japonês, 3 idiomas, 132 bytes, pontuação ~ = 0,205

A="`i96d)p2`i96d)p2";1//2;A=1
S="S=%s;console.log(S,uneval(S))";A//2;S="S=%r;print S%%S";"""
console.log(S,uneval(S))//""";print S%S

Isso imprime

S="S=%s;console.log(S,uneval(S))";console.log(S,uneval(S))

em JavaScript (apenas no Firefox),

S='S=%r;print S%%S';print S%S

em Python 2 e

`i96d)p2`i96d)p2

em Japt. ( Teste online! )

Javascript

Isto é o que o JavaScript vê:

A="`i96d)p2`i96d)p2";1
S="S=%s;console.log(S,uneval(S))";A
console.log(S,uneval(S))

A primeira linha é no-op porque Anão é usada de forma alguma. Os segundo conjuntos de linha Spara a cadeia S=%s;console.log(S,uneval(S)), e os terceiros imprime-o depois substituindo o %scom a unevalrepresentação da ed S(apenas Sentre aspas). O resultado é uma solução em JavaScript.

Python

Isso é basicamente o que o Python vê:

A="`i96d)p2`i96d)p2";1//2;A=1
S="S=%s;console.log(S,uneval(S))";A//2;S="S=%r;print S%%S"
print S%S

A primeira linha é praticamente no-op; a única parte importante é A=1o final. Isso se transforma Aem um número para que a divisão inteira A//2na segunda linha não gere um erro.

A segunda linha é basicamente da mesma maneira, exceto que é definida Scomo a sequência S=%r;print S%%S. A terceira linha é impressa Sapós a substituição da %rrepresentação bruta de S(apenas Sentre aspas simples). O resultado é uma solução em Python 2.

Japt

Este é o código JavaScript que o interpretador Japt vê:

A="`i96d)p2`i96d)p2";1//2;A=1
S="S=%s;console.log(S,uneval(S))";A//2;S="S=%r;print S%%S";"","\nconsole.log(S,uneval(S))//","";.p("r".i("n".t(),S%S))

Como você pode ver, é basicamente o mesmo que a resposta JavaScript, com uma exceção principal: as duas últimas linhas são combinadas. Como resultado, é isso que o intérprete realmente vê:

A="`i96d)p2`i96d)p2";1
S="S=%s;console.log(S,uneval(S))";A

A primeira linha é Adefinida como a coluna Japt e a segunda é Sparte da coluna JS. No Japt, no entanto, apenas a última expressão é enviada para a saída; isto é A, então a saída é `i96d)p2`i96d)p2.

ETHproductions
fonte
O que é uneval? Não funciona para mim
Cyoce
@Cyoce developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Porém, ele só funciona no Firefox.
ETHproductions
3

Jolf +> <>, pontuação = 2 ** 3/15 = 0,533 ....

"r0:g>o<
"Q«Q«

Trabalhando em adicionar outro idioma para isso.

Rɪᴋᴇʀ
fonte
2

> <>, Python 2 e 3, 3 idiomas, 107 bytes, pontuação = 27/107 ~ = 0,252

#o<}-1:"
a=1/1is 1;b="(_%(_,b))"[a:-a|9];_='a=1/1is 1;b="(_%%(_,b))"[a:-a|9];_=%r;print %s';print (_%(_,b))

Experimente on-line: Python 2 , Python 3 , > <>

A saída do Python 3 é exatamente a segunda linha, e a saída do Python 2 é essa solução . A saída> <> é a primeira linha.

Explicação

Este programa é baseado no quine clássico do Python 2:

_='_=%r;print _%%_';print _%_

Primeiro, para torná-lo compatível com o Python 2 e o Python 3, alterei a printinstrução para uma chamada de função e adicionei um espaço extra que será útil mais tarde:

_='_=%r;print (_%%_)';print (_%_)

Em seguida, eu precisava de uma maneira de distinguir o Python 2 do Python 3. Uma das maneiras mais simples é aproveitar o fato de que /é a divisão inteira no Python 2, mas a divisão flutuante no Python 3. Portanto, o código a seguir é avaliado Trueno Python 2, mas Falseem Python 3:

1/1is 1

Para diferenciar as saídas entre os dois idiomas, eu precisava remover seletivamente o primeiro e o último parênteses da printchamada (é por isso que eu precisava do espaço anterior - sem espaço, não seria uma printdeclaração válida no Python 2) . Assim, eu precisava modificar o chicote de fios da seguinte maneira:

a=1/1is 1;b="(_%(_,b))"[a:-a|9];_='a=1/1is 1;b="(_%%(_,b))"[a:-a|9];_=%r;print %s';print (_%(_,b))

Essa expressão é a:-a|9avaliada 0:9no Python 2 e 1:-1no Python 3. Portanto, bestá "(_%(_,b))"no Python 3, mas no Python 2 o primeiro e o último caracteres são descartados, saindo _%(_,b). E com essa modificação, o poliglota foi válido para esse desafio.

Conforme sugerido pelo Teal pelican, a coluna> <> #o<}-1:"pode ser adicionada com bastante facilidade, graças ao fato de #iniciar um comentário de linha única em Python. Basta anexá-lo e uma nova linha adiciona outro idioma e aumenta a pontuação em quase dez vezes.

Mego
fonte
1

Python 2 + Retina, 2 idiomas, 55 bytes, pontuação = 2 ^ 3/55 ≈ 0,145

Eu usei em $nvez de manter os dois ASCII válidos.

S='S=%r;print S%%S';print S%S#|
#$n\(*S1`$n\(*S1`
#\`#

Python , Retina

Python:

S='S=%r;print S%%S';print S%S

Retina:


\(*S1`
\(*S1`
mbomb007
fonte
0

> <> + Pyke + Python 2, 81 bytes, pontuação = 3 ** 3/81 ~ 0,333

"""r00gol?!;60.
a=%r;print a%%a"""#);"34.Cp\D\Es"DEp00/
a=__doc__[-15:]
print a%a

Eu tentei fazer algo diferente com todos os idiomas.

> <> vê:

"""r00gol?!;60.

Esta é uma ligeira modificação do quine padrão> <> para usar uma cadeia de caracteres tripla no início. Isso permite que as aspas triplas finais do Python estejam em uma linha diferente.

Experimente online!

Pyke vê:

"34.Cp\D\Es"DEp00/

Eu não tinha criado uma solução em Pyke antes e, portanto, tive que pensar em uma. Usei técnicas tradicionais de quining para criar uma string e, em seguida, avaliá-la como uma entrada. Observe que, para que isso funcione sem impacto visual, os avisos deverão ser desativados. Erros com uma divisão por 0 erro na etapa de geração.

Experimente aqui! Ou apenas a parte quine.

Python vê:

Tudo. Python usa todo o código para produzir sua solução. Decidi incorporar a parte quine na docstring (embora, em última análise, economizasse bytes para remover, mas acho legal). É uma modificação da técnica de quining padrão.

Experimente online!

Azul
fonte