CJam, ( 58 56 54 48 46 x 2) * 48% = 44,16
{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~
który drukuje
{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~
Znaki spacji w każdym wierszu pozostają takie same między dwoma wzajemnymi quinesami.
Ale teraz naprawdę słodka część:
{`"_~"+{_,94\m2/S*a_+\*{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~N/23f/Wf%N*}_`'"#)!*}_~
jest quine! :)
Sprawdź to tutaj.
Jak to działa
Radzę najpierw przeczytać wyjaśnienie mojego drugiego przesłania, ponieważ wyjaśnia ono podstawy quitingu w CJam w ogóle.
Ten jest nieco trudniejszy. W przypadku wzajemnego quine, podobnie jak w drugim przypadku, modyfikuję reprezentację ciągu bloku, dodając spacje przed lub po każdej linii i zamieniając 0 na 2, tak aby wynikowy program umieszczał spacje na przeciwległym końcu.
Zauważ, że spacje w ogóle nie wpływają na wzajemne quiny. W pierwszym są one w bloku, który tak naprawdę nie jest używany, aw drugim są wokół całego kodu.
Aby uzyskać regularny quine podczas łączenia obu, musimy znaleźć sposób, aby uniknąć wykonywania wszystkich tych modyfikacji. Zauważ, że struktura białych znaków i kodu oznacza, że łącząc oba, wstawiamy całość jednego quine do drugiego. Jeśli więc umieścimy cały kod modyfikacji w bloku, możemy uruchomić ten blok w zależności od jego rzeczywistej zawartości.
Więc teraz mam ten blok ... dla wzajemnych quinesów, zawiera on tylko kod, który faktycznie chcę uruchomić. W przypadku połączonego quine zawiera on ponownie cały quine, w losowej pozycji, co nie ma żadnego sensu ... ale ponieważ jest to blok, nie jest uruchamiany automatycznie. Możemy więc ustalić, czy zmodyfikować ciąg w oparciu o zawartość tego bloku. Po to _`'"#)!
jest. "
Duplikuje blok, konwertuje go na ciąg znaków, wyszukuje znak (który we wspólnych znakach pojawia się tylko poza blokiem) - wyszukiwanie powraca, -1
jeśli znak nie zostanie znaleziony, a dodatnia liczba całkowita w przeciwnym razie - zwiększa wynik i logicznie to neguje. Więc jeśli "
znaleziono a, to daje 0
to inaczej 1
. Teraz po prostu to robimy*
, który wykonuje blok raz, jeśli wynik to 1, a wcale nie.
Wreszcie, tak działa kod modyfikujący:
_,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.";
Odbieranie nagrody (12 x 10) * 48% = 57,6
Okazuje się, że ten kod można bardzo łatwo podzielić na kilka wierszy z pewnymi modyfikacjami. Dodajemy 2 znaki, aby uzyskać 48 z rzędu, które następnie możemy wygodnie podzielić przez 8, dzięki czemu mamy 8 linii z 6 znakami kodu i 6 spacjami. Aby to zrobić, musimy również zmienić kilka liczb i zmienić operator lub dwa, aby nie były podzielone na obie linie. To daje nam działającą wersję o wymiarach 12 x 8 ... jednym z wymagań. Więc dodajemy dwie linie, które nic nie robią (popchnij 1, pop 1, popchnij 1, pop 1 ...), więc przejdź do 12 x 10 :
{`"_~"
+{129X
$,m2/S
*a_+\*
N/6f/1
;1;1;1
;1;1;1
;Wf%N*
}_`'"#
)!*}_~
Tak jak poprzedni, to produkuje
{`"_~"
+{129X
$,m2/S
*a_+\*
N/6f/1
;1;1;1
;1;1;1
;Wf%N*
}_`'"#
)!*}_~
(Uwaga dodatkowa: nie ma potrzeby utrzymywania na przemian lewej i prawej linii pośredniej, ważna jest tylko pozycja pierwszej i ostatniej linii. Lewą i prawą stronę można wybrać dowolnie dla wszystkich innych linii).
I przez czysty zbieg okoliczności cały quine nadal działa:
{`"_~"{`"_~"
+{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*
}_`'"#}_`'"#
)!*}_~)!*}_~
(Mówię przypadek, ponieważ część, która zajmuje się niewykonywaniem wewnętrznego kodu, jest teraz dziwnie przeplatana z innym quine, ale nadal działa dobrze.)
Biorąc to pod uwagę, mogłem właśnie dodać 44 wiersze 1;
do mojego oryginalnego zgłoszenia, aby spełnić wymóg nagrody, ale 12 x 10
wygląda to znacznie ładniej. ;)
Edycja: Haha, kiedy powiedziałem „czysty zbieg okoliczności”, nie mogłem być bardziej na miejscu. Spojrzałem na to, jak teraz działa ostatnia quine, i jest to absolutnie śmieszne. Istnieją trzy zagnieżdżone bloki (właściwie 4, ale najbardziej wewnętrzna nie ma znaczenia). Jedyną ważną częścią najbardziej wewnętrznego z tych 3 bloków jest to, że zawiera "
(a nie ten, który zrobił w oryginalnym zgłoszeniu, ale ten, '"
który jest używany na końcu, aby sprawdzić ten sam znak). Podstawowa struktura quine to:
{`"_~"{`"_~"+{___'"___}_`'"#)!*}_~)!*}_~
Przeanalizujmy:
{`"_~" }_~ "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.";
To rzeczywiście robi zabawną magię, ale ponieważ blok wewnętrzny pozostawia pojedynczy stos na stosie, )!*
zdarza się, że zamienia go w pusty ciąg. Jedynym warunkiem jest to, że elementy w wewnętrznym bloku później +
nie robią nic więcej na stosie, więc spójrzmy na to:
{___'"___} "Push a block which happens to contain
quotes.";
_`'"#)!* "This is from the original code and just
removes the block if it does contain
quotes.";