CJam, ( 58 56 54 48 46 x 2) * 48% = 44,16
{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~
que imprime
{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~
Os caracteres não espaciais em cada linha permanecem os mesmos entre os dois quines mútuos.
Mas agora a parte realmente doce:
{`"_~"+{_,94\m2/S*a_+\*{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~N/23f/Wf%N*}_`'"#)!*}_~
é um quine! :)
Teste aqui.
Como funciona
Eu recomendo que você leia a explicação em minha outra submissão primeiro, uma vez que explica os conceitos básicos de quining no CJam em geral.
Este é um pouco mais complicado. Para o quine mútuo, como no outro caso, modifico a representação em cadeia do bloco adicionando espaços antes ou depois de cada linha e trocando um 0 por um 2, para que o programa resultante coloque os espaços na extremidade oposta.
Observe que os espaços não afetam de maneira alguma os quines mútuos. No primeiro, eles estão em um bloco, que na verdade não é usado, e no segundo, em torno de todo o código.
Para obter um quine regular ao combinar os dois, precisamos encontrar uma maneira de evitar fazer toda essa modificação. Observe que a estrutura do espaço em branco e do código significa que, combinando ambos, inserimos a totalidade de um quine no outro. Portanto, se colocarmos todo o código de modificação em um bloco, podemos executá-lo dependendo do seu conteúdo real.
Então agora eu tenho esse bloco ... para os quines mútuos, ele contém apenas o código que realmente quero executar. Para o quine combinado, ele também contém todo o quine novamente, em uma posição aleatória, o que não faz sentido ... mas, como é um bloco, não é executado automaticamente. Portanto, podemos determinar se a string deve ser modificada com base no conteúdo desse bloco. É para isso que _`'"#)!
serve. Duplica o bloco, converte-o em uma cadeia de caracteres, procura o caractere "
(que, nas linhas comuns, aparece apenas fora do bloco) - a pesquisa retorna -1
se o caractere não for encontrado e, caso contrário, um número inteiro positivo -, incrementa o resultado e nega isso logicamente. Portanto, se um "
foi encontrado, isso cede de 0
outra forma 1
. Agora apenas fazemos*
, que executa o bloco uma vez, se o resultado for 1 e não for o caso.
Finalmente, é assim que o código modificador funciona:
_,94\m2/S*a_+\*N/23f/Wf%N*
_, "Duplicate the quine string and get its length.";
94\m "Subtract from 94.";
2/ "Divide by two.";
S* "Create a string with that many spaces. This will be
an empty string for the first mutual quine, and contain
23 spaces for the second mutual quine.";
a_+ "Create an array that contains this string twice.";
\* "Join the two copies together with the quine string.";
N/ "Split into lines.";
23f/ "Split each line into halves (23 bytes each).";
Wf% "Reverse the two halves of each line.";
N* "Join with a newline.";
Reivindicação da recompensa, (12 x 10) * 48% = 57,6
Acontece que esse código pode ser dividido em mais linhas com muita facilidade com algumas modificações. Adicionamos 2 caracteres, para obter 48 em uma linha, que podemos dividir convenientemente por 8, para que possamos ter 8 linhas com 6 caracteres de código e 6 espaços. Para fazer isso, também precisamos alterar alguns números e reorganizar um operador ou dois, para que eles não sejam divididos nas duas linhas. Isso nos dá uma versão de trabalho com tamanho 12 x 8 ... uma fora do requisito. Então, apenas adicionamos duas linhas que não fazem nada (pressione 1, digite 1, digite 1, digite 1 ...), para obter 12 x 10 :
{`"_~"
+{129X
$,m2/S
*a_+\*
N/6f/1
;1;1;1
;1;1;1
;Wf%N*
}_`'"#
)!*}_~
Como o anterior, isso produz
{`"_~"
+{129X
$,m2/S
*a_+\*
N/6f/1
;1;1;1
;1;1;1
;Wf%N*
}_`'"#
)!*}_~
(Observação: não há necessidade de continuar alternando a esquerda e a direita nas linhas intermediárias, apenas a posição da primeira e da última linha é importante. A esquerda e a direita podem ser escolhidas arbitrariamente para todas as outras linhas.)
E por pura coincidência, o quine completo também funciona:
{`"_~"{`"_~"
+{129X+{129X
$,m2/S$,m2/S
*a_+\**a_+\*
N/6f/1N/6f/1
;1;1;1;1;1;1
;1;1;1;1;1;1
;Wf%N*;Wf%N*
}_`'"#}_`'"#
)!*}_~)!*}_~
(Digo coincidência, porque a parte que cuida de não executar o código interno agora fica estranhamente intercalada com a outra, mas ainda funciona bem.)
Dito isto, eu poderia ter adicionado 44 linhas 1;
à minha inscrição original para cumprir o requisito de recompensa, mas 12 x 10
parece muito mais organizado. ;)
Edit: Haha, quando eu disse "pura coincidência" eu não poderia estar mais no local. Eu examinei como a solução final agora realmente funciona, e é absolutamente ridículo. Existem três blocos aninhados (4 na verdade, mas o mais interno é irrelevante). A única parte importante do mais interno desses 3 blocos é que ele contém um "
(e não o que ele fez na submissão original, mas o '"
que é usado no final para verificar esse mesmo caractere). Portanto, a estrutura básica do quine é:
{`"_~"{`"_~"+{___'"___}_`'"#)!*}_~)!*}_~
Vamos dissecar isso:
{`"_~" }_~ "The standard CJam quine.";
{`"_~"+ }_~ "Another CJam quine. Provided it doesn't do
anything in the rest of that block, this
will leave this inner block as a string on
the stack.";
) "Slice the last character off the string.";
! "Negate... this yields 0.";
* "Repeat the string zero times.";
Portanto, isso realmente faz alguma mágica engraçada, mas como o bloco interno deixa uma única string na pilha, )!*
isso transforma uma string vazia. A única condição é que as coisas no bloco interno depois +
não façam mais nada na pilha, então vamos ver isso:
{___'"___} "Push a block which happens to contain
quotes.";
_`'"#)!* "This is from the original code and just
removes the block if it does contain
quotes.";