Quines seguros para cotação

17

Sua tarefa é simples: escreva um programa (ou função) que não aceite e não envie (ou retorne) seu código-fonte. O problema é que, quando o programa é empacotado "quotes"(caractere Unicode 34), ele deve emitir novamente seu código-fonte (agora citado).

Aplicam-se regras padrão para quines. Isso é , então o programa mais curto (em bytes) vence.

Esolanging Fruit
fonte
8
@ATaco pense criativamente. O código entre aspas normalmente não é executado, mas quando o programa inteiro está entre aspas, essas seções são executadas.
Pavel
11
Hmm, bom ponto.
ATaco 27/01
Isso pode funcionar com a BF em implementações que suportam !...
Esolanging Fruit
11
Você deve usar "? Alguns idiomas suportam dois ou três caracteres de aspas.
Neil
11
@tkellehe Meta: O que conta como uma solução adequada? Tanto quanto eu entendo o seu quine de 1 byte, ele viola o requisito de código / dados formulado na publicação com a maior votação.
Laikoni 27/01

Respostas:

4

Noodel , 9 7 bytes

Esta versão funciona da mesma maneira que a outra, só que eu esqueci que o Noodel tem uma maneira de executar um bloco de código uma vez e eu fiz o idioma ...

Ḷ1ḥ-Ð1ḥ@€

ḷḥ-Ðḥ@ḅ

Tente:)


Como funciona

ḷḥ-Ðḥ@ḅ # Single statement that builds itself as a string.
ḷ       # Loop the following block of code unconditionally.
 ḥ-     # Push the string literal of the token preceding this one which pushes "ḷ" onto the stack.
   Ð    # Push the stack as an array to stdout (since is an array it is done by reference).
    ḥ@  # Push the string literal for this block of code which pushes "ḥ-Ðḥ@ḅ" onto the stack.
      ḅ # Break out of the given loop. (The stack is now ["ḷ", "ḥ-Ðḥ@ḅ"]).

        # The top of the stack is popped off and displayed which modifies the array to produce {["ḷ"], "ḥ-Ðḥ@ḅ"} in stdout.

Quote-Safety

A colocação do "caractere antes e depois do programa funciona porque o Noodel possui um conjunto de caracteres dedicados ao que chamo de imprimíveis . Eles são analisados ​​imediatamente como literais de string quando colocados sozinhos e permitem imprimir facilmente algo na tela. Portanto, diferentemente da maioria dos idiomas, Noodel vê o conjunto ASCII normal que é considerado digno de impressão como literal de string direta (exceto espaço e alimentação de linha), citando o código apenas como sendo pressionado por strings.

"ḷḥ-Ðḥ@ḅ"

"         # Pushes on the string literal "\"" onto the stack.

 ḷḥ-Ðḥ@ḅ  # Same execution as before, simply builds the Quine for this loop.
 ḷ        # Loop the following block of code unconditionally.
  ḥ-      # Push the string literal of the token preceding this one which pushes "ḷ" onto the stack.
    Ð     # Push the stack as an array to stdout (since is an array it is done by reference).
     ḥ@   # Push the string literal for this block of code which pushes "ḥ-Ðḥ@ḅ" onto the stack.
       ḅ  # Break out of the given loop. (The stack is now ["\"", "ḷ", "ḥ-Ðḥ@ḅ"]).

        " # Pushes on the string literal "\"" onto the stack.

          # The top of the stack is popped off and displayed which modifies the array to produce {["\"", "ḷ", "ḥ-Ðḥ@ḅ"], "\""} in stdout.

"Tente:)"


Trechos

<div id="noodel" code='ḷḥ-Ðḥ@ḅ' input="" cols="10" rows="1"></div>
<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>


<div id="noodel" code='"ḷḥ-Ðḥ@ḅ"' input="" cols="10" rows="1"></div>
<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>

tkellehe
fonte
Eu não acho que usar eé válido. A pergunta não pede o caractere codificado como o byte 34, mas o caractere Unicode 34. Independentemente da codificação usada, existe apenas um:"
Dennis
@ Dennis, estou adivinhando o que você está dizendo é que a referência ao caractere Unicode 34 era apenas para garantir que todos usassem o mesmo "? (Desculpe, apenas tentando ter certeza de que entendi o que você está dizendo) Além disso, devo remover todo o texto da resposta referente ao uso e?
precisa saber é
11
Sim, existem milhares de codificações, mas apenas um conjunto de caracteres Unicode. Como "funciona, eu apenas removia a discussão e simplesmente usava ".
Dennis
11

Python 2 3, 181 152 130 124 122 bytes

""" """>" "or exec("oct=0");p='"""" """>" "or exec("oct=0");p=%r;a=oct==0;print(p[a:~a]%%p)#".';a=oct==0;print(p[a:~a]%p)#

Experimente online! O TIO vem com um cabeçalho e rodapé que testa automaticamente a validade do quine. Você pode limpá-los para apenas executar o quine.

Esse código funciona usando as seqüências de caracteres triplas no Python. """ """é igual a ' 'e """" """é igual a '" '.

O código usa exec, mas não a maneira "não-eficiente" de executar dados como código, apenas para definir uma variável de dentro de uma expressão. oexec está codificado corretamente nos dados.

A primeira instrução compara a string, possivelmente com uma citação anexada, a " "e define a variáveloct acordo. (A variável poderia ter sido curta).

O restante do código implementa a quine tradicional do Python usando %rformatação de string, com algum código adicional que retira as aspas extras seoct não for alterado.

Uma versão alternativa usando o "barato" execvem em 126 bytes com menos código repetido:

""" """>" "and exec("oct=0");s='"""" """>" "and exec("oct=0");s=%r;p=%r;exec(p)#".';p='a=oct!=0;print(s[a:~a]%(s,p))';exec(p)#

Experimente online!

PurkkaKoodari
fonte
7

StandardML , 182 176 108 bytes

";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))

Versão sem aspas : Experimente no codingground.
Versão citada : Experimente no codingground.

Observe que a saída se parece com isso

> val it = "{some string}" : string
> val it = "{some string}" : string
{output to stdout}> val it = fn : string -> unit

porque o código é interpretado declaração por declaração (cada ;uma termina uma declaração) e mostra o valor e o tipo de cada declaração.


fundo

No SML, existe um quine do formulário <code>"<code in quotes>":

str(chr 34);(fn x=>print(x^it^x^it))"str(chr 34);(fn x=>print(x^it^x^it))" 

e um na forma "<code in quotes>"<code>:

";str(chr 34)^it;print(it^it)";str(chr 34)^it;print(it^it)

Ambos confiam no fato de que a <code>parte-não contém aspas e, portanto, pode ser citada sem a necessidade de escapar de nada, o "necessário para produzir a coluna é dado porstr(chr 34) .

Eles também dependem muito do identificador implícito itque é usado quando nenhum identificador explícito é fornecido em uma declaração.

Na primeira linha, str(chr 34);liga it- se à cadeia que contém" , fn x=>inicia uma função anônima usando um argumento x, concatena x^it^x^ite imprime a string resultante. Essa função anônima é aplicada diretamente a uma sequência que contém o código do programa, portanto a concatenação x^it^x^itgera<code>"<code>" .

O segundo quine começa com apenas o código do programa como string ao ";str(chr 34)^it;print(it^it)";qual está vinculado it. Entãostr(chr 34)^it; concatena uma cotação para o início da sequência e, como nenhum identificador explícito é fornecido, a sequência resultante "<code>é vinculada it. Por fim, print(it^it)concatena a string com ela mesma, produzindo a "<code>"<code>qual é impressa.


Explicação

Editar: não está mais atualizado com a versão de 108 bytes, no entanto, pode-se entender também depois de ler esta explicação.

O quine seguro para cotação combina as duas abordagens acima e é ele próprio da forma "<code>"<code>. Colocando isso novamente entre aspas ""<code>"<code>", obtemos uma string vazia e, em seguida, uma coluna da outra forma.

Isso significa que o programa recebe sua própria fonte no formulário "<code>pelo identificador itou ité justo "e recebemos nossa própria fonte<code> como argumento e, portanto, deve ser uma função que lida com esse argumento.

(if size it>1then(print(it^it);fn _=>())else fn x=>print(it^it^x^it^x^it))

Para identificar em qual caso estamos, verificamos se o tamanho de ité maior que 1. Se não, então ité "e estamos no segundo caso, portanto, a elseparte-retorna uma função anônimafn x=>print(it^it^x^it^x^it) que é chamada então porque é seguida pela origem como string . Observe a liderança it^it^necessária para a sequência vazia no início do programa.

Se size itfor maior que 1, estamos na thenparte e apenas executamos print(it^it), certo? Não exatamente porque deixei de lhe dizer que SML é fortemente tipado, o que significa que uma condicional if <cond> then <exp_1> else <exp_2>deve sempre ter o mesmo tipo, o que novamente significa que as expressões <exp_1>e <exp_2>precisam ter o mesmo tipo. Já sabemos o tipo da elsepeça: uma função anônima que pega uma string e depois chama printpossui type string -> <return type of print>, e printtype string -> unit( unité de alguma forma semelhante a voidoutros idiomas), portanto o tipo resultante é novamentestring -> unit .

Portanto, se a thenpeça tivesse apenas o print(it^it)tipo unit, receberíamos um erro de incompatibilidade de tipo. Então, que tal fn _=>print(it^it)? ( _é um curinga para um argumento que não é usado) Essa função anônima, por si só, possui um tipo 'a -> unitonde 'arepresenta um tipo arbitrário; portanto, no contexto de nossa condicional que aplica um string -> unittipo, isso funcionaria. (A variável type 'aé instanciada com type string.) No entanto, nesse caso, não imprimiríamos nada, pois a função anônima nunca é chamada! Lembre-se, quando entramos na thenparte -part, o código geral é "<code>"<code>, então a <code>parte-avalia como uma função, mas, como nada vem depois dela, ela não é chamada.

Em vez disso, usamos uma sequencialização que tem a forma para (<exp_1>; ...; <exp_n>)onde pode ter tipos arbitrários e o tipo de fornece o tipo de toda a sequencialização. Do ponto de vista funcional, os valores de to são simplesmente descartados, no entanto, o SML também suporta construções imperativas, para que as expressões possam ter efeitos colaterais. Em resumo, tomamos como parte, imprimindo primeiro e retornando a função que tem o tipo correto.<exp_1><exp_n-1><exp_n><exp_1><exp_n-1>(print(it^it);print)thenprint

Laikoni
fonte
7

V , 27 , 23 bytes

éPñi"éP241"qpá"lxx|xÿ

Experimente online!

Como contém alguns caracteres não imprimíveis, aqui está uma versão legível:

éPñi"éP<C-v>241<esc>"qpá"lxx|xÿ

e aqui está um hexdump:

00000000: e950 f169 22e9 5016 3234 311b 2271 70e1  .P.i".P.241."qp.
00000010: 226c 7878 7c78 ff                        "lxx|x.

Então a primeira coisa que precisamos fazer é determinar se o primeiro caractere é uma citação. éPinsere um caractere de 'P', mas "éPé um NOOP. Depois disso, corremos uma ligeira modificação na Quine extensível padrão, que é:

ñi<C-v>241<esc>"qpÿ

Nós vamos fazer isso de maneira um pouco diferente. Primeiro, precisamos inserir o texto "éP" inicial. Então nós fazemos

ñ                        " Start recording into register 'q'
 i                       " Enter insert mode
  "éP<C-v>241<esc>       " Enter the following text: '"éPñ'
                  "qp    " Paste the text in register 'q'
                     á"  " Append a '"'

Aqui é onde a ramificação acontece. O texto atualmente no buffer é

"éPñi"éP<C-v>241<esc>"qpá"P
Cursor is here ----------^

A menos que envolveu-o entre aspas, nesse caso, o 'P' nunca teria sido inserido, e o buffer é:

"éPñi"éP<C-v>241<esc>"qpá"
Cursor is here ----------^

Como ainda estamos gravando, podemos fazer o que quisermos aqui, e ele será adicionado ao buffer quando isso "qpacontecer. Portanto, a partir daqui, é muito fácil excluir as aspas condicionalmente:

l           " Move one character to the right. If there is no character to the right, 
            " then this is effectively a "break" statement, stopping playback of the recording
 xx         " Delete two characters (the '"P')
   |        " Move to the first character on this line
    x       " Delete one character
     ÿ      " End the program
DJMcMayhem
fonte
3

JavaScript (ES6), 239 237 bytes

Set=``;eval(";a='Set=``;eval(~;a=1;S=String.fromCharCode;q=S(34);r=Set&&q;s=S(39);alert(r+a.replace(/[^ -}]/g,q).replace(1,s+a+s)+r);~)';S=String.fromCharCode;q=S(34);r=Set&&q;s=S(39);alert(r+a.replace(/[^ -}]/g,q).replace(1,s+a+s)+r);")

Tente experimentar cada versão em um ambiente novo (por exemplo, uma nova guia do navegador)

Tem que haver pelo menos uma maneira de simplificar isso ...

ETHproductions
fonte
11
Suponho que você possa usar uma matriz para as substituições da seguinte forma: [x = "replace"]. Pode quebrar as coisas, porém, eu não sou muito experiente com quines ...
Lucas