Zostało to zainspirowane przez Print Negative of Your Code i Golf a quine quine .
Rozważ prostokąt znaków, które spełniają następujące ograniczenia:
- Składa się wyłącznie z drukowalnych znaków ASCII
- Wymiary oba większe niż 1
- Każdy wiersz i każda kolumna zawiera co najmniej jedną spację.
- Każdy wiersz i każda kolumna zawiera co najmniej jeden znak spacji.
Na przykład poniżej jest prawidłowy prostokąt 6x4:
%n 2e
1 g 3
&* __
3
Ujemny tego prostokąta jest zdefiniowana jako prostokąt o równych wymiarach i zastąpiono wszystkie miejsca w postaci innych niż miejsca, a wszystkie nie-space zastąpione przestrzeni. Negatyw powyższego prostokąta może być:
f ^
33 >
9 $
^ }|Q'
Do zamiany spacji można użyć dowolnego drukowalnego znaku ASCII spacji.
Zadanie
Twoim zadaniem jest napisanie programu z prostokątnym kodem źródłowym, który wyprowadza do siebie ważny negatyw. Wynik negatywny musi być również poprawnym programem w tym samym języku, co oryginał, i musi generować źródło oryginału.
Żadnych końcowych białych znaków nie można dodawać ani usuwać, z wyjątkiem jednej końcowej nowej linii na końcu obu danych wyjściowych, która jest opcjonalna.
Żaden program nie może odczytać kodu źródłowego żadnego z nich; nie można również zakładać środowisk REPL.
Punktacja
Twój wynik jest iloczynem wymiarów twojego kodu (tj. Jeśli twój kod źródłowy znajduje się w prostokącie 12 na 25, twój wynik to 12 * 15 = 180). Dodatkowo, za każdy znak użyty w komentarzu, twój wynik zwiększa się o 2 (jeśli użyjesz /* .. */
raz w kodzie, a twój kod znajduje się w prostokącie 10 na 10, twój wynik wyniesie 10 * 10 + 8 * 2 = 116).
Najniższy wynik wygrywa.
W przypadku remisu wygrywa zgłoszenie z najmniejszą liczbą spacji w programie (oryginalne lub negatywne, w zależności od tego, która z nich ma mniej spacji).
Jeśli nadal pozostaje remis, wcześniejsza odpowiedź wygrywa.
Istnieje premia w wysokości -52% , jeśli połączenie oryginału i negatywu razem daje normalny quine. Na przykład:
Original Negative Combined
A A B B BABA
A A B B ABAB
źródło
Odpowiedzi:
CJam, (
51 49 47 46 4542 x 2) * 48% = 40,32Uruchomienie powyższego kodu daje następujące dane wyjściowe:
uruchomiony, który drukuje oryginalne źródło.
Źródło i dane wyjściowe to po prostu zamienione linie.
Teraz nadchodzi magia.
Nakładanie się źródła i danych wyjściowych powoduje powstanie następującego kodu:
który jest idealnym quine!
Wypróbuj je online tutaj
Jak to działa
Cała logika drukowania znajduje się w samym pierwszym wierszu, który obsługuje wszystkie trzy przypadki wyjaśnione później.
Tablica w ostatnim wierszu powyżej to tablica, która zawiera bloki kodu odpowiadające wszystkim trzem przypadkom.
Przypadek 1
W tym przypadku długość pozostałego stosu wynosiła 0, ponieważ gdy blok był wykonywany, miał tylko kopię samego bloku, który początkowo wyskoczył w trzecim kroku powyżej. Więc wyjmujemy indeks
0
z ostatniej tablicy i wykonujemy go:W tym przypadku druga linia nie ma opozycji, jeśli chodzi o drukowanie danych wyjściowych.
Przypadek 2
W tym przypadku stos zawierał już pusty ciąg, więc gdy wykonano skopiowany blok kodu, miał 2 elementy - pusty ciąg i sam blok kodu. Więc wyjmujemy indeks
1
z ostatniej tablicy i wykonujemy go:Przypadek 3
W tym przypadku stos ma 6 elementów. Zatem po usunięciu ostatniego bloku kodu pozostała długość tablicy wynosi 5. Wyjmujemy indeks
5
z tablicy i wykonujemy go. (Zauważ, że w tablicy3
elementów indeksem5
jest indeks5%3 = 2
)źródło
Python, 97x2 + 2 = 196
Nie jest to świetne rozwiązanie na początek, ale przynajmniej działa (tak myślę).
Wydajność:
źródło
CJam, (
5856544846 x 2) * 48% = 44,16który drukuje
Znaki spacji w każdym wierszu pozostają takie same między dwoma wzajemnymi quinesami.
Ale teraz naprawdę słodka część:
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 daje0
to inaczej1
. 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:
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 :
Tak jak poprzedni, to produkuje
(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:
(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, ale12 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:
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:źródło
Y/2
w połączonym quine?CJam,
423733 x 2 = 66który drukuje
(Linie są zamieniane, a a
1
zamienia się w a0
.)Sprawdź to tutaj.
Jak to działa
Po pierwsze, powinieneś zrozumieć podstawową quine CJam:
Nawiasy klamrowe po prostu definiują blok kodu, taki jak funkcja, która nie jest natychmiast wykonywana. Jeśli niewykorzystany blok pozostaje na stosie, drukowany jest jego kod źródłowy (w tym nawiasy klamrowe).
_
powiela blok i~
wykonuje drugą kopię. Sam blok po prostu popycha ciąg zawierający_~
. Tak więc ten kod pozostawia stos w następującym stanie:Blok i ciąg znaków są po prostu drukowane jeden po drugim na końcu programu, co czyni to quine.
Piękno tego polega na tym, że możemy robić, co chcemy w bloku, i pozostaje to quine, ponieważ każdy fragment kodu zostanie automatycznie wydrukowany w zawartości bloku. Możemy również zmodyfikować blok, uzyskując jego reprezentację ciągu
`
(który jest tylko ciągiem bloku z nawiasami klamrowymi).Teraz spójrzmy na to rozwiązanie. Zauważ, że każda część wzajemnej quine zawiera blok podobny do quine z
_~
i anL
.L
Popycha pusty ciąg na stosie, który nie przyczynia się do wyjścia. Oto, co robi blok:To zrobi część quine, ale zamieni 1 na 0, a także wstawi kolejną linię z
L
, gdzie w powyższym kodzie jest spacja. Połów polega na tym, że kolejność tych dwóch linii jest określona przez zamianę wewnątrz{ }*
. A ponieważ zewnętrzna część wzajemnego quine ma0
przednią część zastąpioną przez1
, nigdy nie wykonuje tej zamiany, a tym samym ponownie generuje pierwotny porządek.źródło
CJam, 27 × 2 = 54
Wydajność:
'A'B>
porównuje znaki A i B.' '\n >
zwraca 1, ponieważ 32> 10 i' \n' >
zwraca 0, ponieważ dwie spacje są równe.źródło
CJam,
3029 x 2 = 58Wyjścia:
który wyprowadza oryginalne źródło.
Jest to oparte na tej samej zasadzie, co moje inne rozwiązanie.
Wypróbuj online tutaj
źródło