Haskell , 3 quines, 1119 bytes
Quine 1, 51 bytes
Uma IOação anônima que imprime diretamente no stdout.
putStr`mappend`print`id`"putStr`mappend`print`id`"
Experimente online!
Quine 2, 265 bytes
A função fpega um argumento fictício e retorna uma string.
f c=[b=<<g]!!0++show g;b c=[[[show 9!!0,show 1!!0..]!!6..]!!c];g=[93,0,90,52,82,89,52,51,51,94,84,24,24,39,34,34,106,95,102,110,0,94,50,89,0,90,52,82,82,82,106,95,102,110,0,48,24,24,39,35,106,95,102,110,0,40,24,24,39,37,37,84,24,24,45,37,37,84,24,24,90,84,50,94,52]
Experimente online!
Quine 3, 803 bytes
Tudo depois do LANGUAGEpragma é uma função desagradável, que pega um argumento fictício e retorna uma string.
{-#LANGUAGE CPP#-}(\q(_:_:_:_:_:_:_:_:z)y(#)_->(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z)'\''__TIME__(\(?)v k x->v$k?x)$ \(&)(%)v->v&'{'&'-'&'#'&'L'&'A'&'N'&'G'&'U'&'A'&'G'&'E'&' '&'C'&'P'&'P'&'#'&'-'&'}'&'('%'\\'&'q'&'('&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'z'&')'&'y'&'('&'#'&')'&'_'&'-'&'>'&'('&'y'&'('%'\\'&'k'&' '&'x'&'-'&'>'%'\''&'&'%'\''&':'&'q'&':'&'k'&':'&'q'&':'&'x'&')'&'#'&'y'&'('%'\\'&'k'&' '&'x'&'-'&'>'%'\''&'%'%'\''&':'&'q'&':'%'\''%'\\'%'\\'%'\''&':'&'k'&':'&'q'&':'&'x'&')'&'$'&'y'&'('&':'&')'&'#'&'y'&'('&':'&')'&'$'&' '%'\\'&'x'&'-'&'>'&'x'&')'&'z'&')'%'\''%'\\'%'\''%'\''&'_'&'_'&'T'&'I'&'M'&'E'&'_'&'_'&'('%'\\'&'('&'?'&')'&'v'&' '&'k'&' '&'x'&'-'&'>'&'v'&'$'&'k'&'?'&'x'&')'&'$'&' '%'\\'&'('&'&'&')'&'('&'%'&')'&'v'&'-'&'>'&'v'
Experimente online!
Personagens
Quine 1:
"S`adeimnprtu
Quine 2:
!+,.0123456789;<=[]bcfghosw
Quine 3:
#$%&'()-:>?ACEGILMNPTU\_kqvxyz{}
Como funciona
Quine 1
putStr`mappend`print`id`"putStr`mappend`print`id`"
Quine 1 é uma versão modificada do meu recente Golf, uma resposta quine (com melhorias de H.PWiz):
- Como os programas completos não são necessários,
main=foi removido.
<>e $foram substituídos por seus quase sinônimos mappende id.
Isso libera os caracteres vitais =<>e o operador útil $para as outras peças.
Quine 2
f c=[b=<<g]!!0++show g;b c=[[[show 9!!0,show 1!!0..]!!6..]!!c];g=[93,0,......]
O Quine 2 usa métodos semelhantes para programar 2 da minha recente resposta mutuamente exclusiva do Quines , mas adaptado para se ajustar diretamente e especialmente para evitar o uso de caracteres literais, necessários para o quine 3. Ambos são alcançados com a ajuda da showfunção, que por pura sorte ainda não teve nenhum de seus personagens.
Esse quine usa guias em vez de espaços, mas usei os espaços abaixo para facilitar a leitura.
gsão os dados quine, como uma lista de números inteiros no final do código. Cada número representa um caractere do restante do código.
- Os números são alterados
9, de modo que a guia é 0. Isso torna a codificação um pouco mais curta, permitindo que as letras minúsculas da função e dos nomes das variáveis caibam em 2 dígitos.
b c=[[[show 9!!0,show 1!!0..]!!6..]!!c] é uma função para converter um número em um caractere (na verdade, uma cadeia de um caractere).
[[show 9!!0,show 1!!0..]!!6..]é um intervalo de caracteres que começa com um caractere de tabulação indexado em !!c.
- O próprio caracter separador é produzido por indexar para outra gama
[show 9!!0,show 1!!0..], começando com os caracteres de dígitos '9'e '1'e salta para baixo em intervalos de 8.
- Os caracteres do dígito são produzidos pela indexação na
showsequência do dígito correspondente.
f c=[b=<<g]!!0++show gé a função principal. cé um argumento fictício.
b=<<gusa =<<para converter cada número em gseu caractere. (O uso de, =<<e não por exemplo, mapé o motivo pelo qual ele bprecisa agrupar seu caractere retornado em uma lista.)
show gfornece a representação da glista de ++strings e concatena as strings.
- Como
=<<tem precedência menor que ++, é necessário algum bracketing. Para evitar o uso ()(reservado para o quine 3), [...]!!0indexe em uma lista com um elemento.
Quine 3
Por design dos outros quines, o quine 3 ainda tem acesso a parênteses, expressões lambda, literais de caracteres e o construtor string / list :. Isso será suficiente para construir uma função que precede o código do quine a uma string.
Infelizmente, todas as vogais em letras minúsculas (exceto algumas vezes y) foram usadas, não deixando funções internas alfanuméricas úteis. Também []""se foram. Isso não deixa uma maneira normal de construir uma string vazia para começar a fingir o código.
No entanto, quase todas as letras maiúsculas ainda estão disponíveis, portanto, LANGUAGEé possível um pragma para obter uma extensão de idioma. Novamente, por pura sorte, CPP(ativar o pré-processador C) é a única extensão de idioma nomeada apenas com letras maiúsculas. E macros CPP geralmente têm nomes em maiúsculas.
Portanto, para obter a string vazia essencial, o quine ativa CPP, usa a __TIME__macro para obter uma constante de string da forma "??:??:??"(convenientemente garantido que sempre tenha o mesmo comprimento) e as correspondências de padrões nela.
{-#LANGUAGE CPP#-}(\q(_:_:_:_:_:_:_:_:z)y(#)_->(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z)'\''__TIME__(\(?)v k x->v$k?x)$ \(&)(%)v->v&'{'&'-'&......
Após o pragma da linguagem, o quine consiste em uma expressão lambda vinculando seus parâmetros a esses quatro argumentos (deixando um parâmetro fictício final _para ser aplicado posteriormente):
qvinculado a '\'', fornecendo um caractere de aspas simples;
_:_:_:_:_:_:_:_:zobrigado a __TIME__, também conhecido como uma string "??:??:??", criando assim zuma string vazia;
yligado a (\(?)v k x->v$k?x), um combinador lambda usado para ajudar a converter os dados do quine da forma associada à esquerda ("foldl") para a forma associada à direita ("foldr");
- O operador
(#)vinculado a \(&)(%)v->v&'{'&'-'&..., os próprios dados quine.
Os dados quine são fornecidos em uma forma de codificação da Igreja, uma expressão lambda com parâmetros (&)(%)v.
- Aplicando a expressão a valores específicos para instanciar
(&), (%)e v, essa codificação pode ser usada para construir o código principal do quine ou para reconstruir a própria representação de dados do quine.
- Pela regra de fixidez padrão de Haskell, torne
&- %se operadores associativos deixados dentro do lambda. Assim, os parâmetros dos caracteres são combinados com o inicial vinicial da esquerda.
- Para a maioria dos caracteres
k, existe um correspondente &'k'.
- Quando
ké 'ou \, que precisa ser escapado dentro dos literais de caracteres, a codificação é alternativa %'\k'.
Como a codificação de dados é deixada associativa, mas as seqüências são construídas da maneira associativa correta, o combinador y = (\(?)v k x->v$k?x)é introduzido para preencher a incompatibilidade.
y(...)destina-se a criar funções adequadas para uso como dados (&)e (%)operadores do quine .
vé uma função de cadeias de caracteres para cadeias de caracteres (os dados pretendidos do quine vsão exemplos).
ké um caractere, xuma sequência e ?um operador que os combina em uma nova sequência. (Para o código principal (?)=(:). Para realmente reconstruir a representação de dados quine, é mais complicado.)
- Assim
y(?)v k = \x->v$k?xé outra função de strings para strings.
Como um exemplo de como isso muda a associatividade, se (&)=y(:):
(v&k1&k2&k3) x
= (((v&k1)&k2)&k3) x
= y(:)(y(:)(y(:)v k1)k2)k3 x
= y(:)(y(:)v k1)k2 (k3:x)
= y(:)v k1 (k2:(k3:x))
= v (k1:(k2:(k3:x)))
= v (k1:k2:k3:x)
De maneira mais geral, quando (#)é a função de dados quine e f1,f2são funções que combinam caracteres com seqüências de caracteres:
(y(f1)#y(f2)$v) x
= (...(y(f1)(y(f1)v '{') '-')...) x
= v(f1 '{' (f1 '-' (... x)))
aplicar a função de dados quine com (&)=y(f1)e (%)=y(f2), e isso usa o prescrito f1e f2para combinar os caracteres dos dados quine com xe, em seguida, passa a sequência resultante para v.
O corpo da expressão principal lambda reúne tudo isso:
(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z
'&':q:k:q:xpara um caractere kprecede &'k'a sequência x, enquanto '%':q:'\\':k:q:xprecede %'\k', que são seus formulários originais de dados quine.
- Assim,
y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:xsão os parâmetros corretos para reconstruir a representação de dados quine, anexados à final z(a sequência vazia) e depois transmitidos à função a seguir.
y(:)#y(:) são os parâmetros corretos para acrescentar o código principal do quine a uma string, sem outra modificação.
- Finalmente, o
\x->xque não faz nada com o quine construído, que é retornado.