Uwaga: To wyzwanie pozwala na odpowiedzi tylko w skompilowanych językach
Zadanie
Twoje zadanie jest dość proste, stwórz dwa różne programy, które po skompilowaniu dają to samo wyjście.
Punktacja
Tutaj zaczyna się zabawa. Twój wynik będzie liczbą unikatowych bajtów obecnych w dokładnie jednym programie. Na przykład, jeśli masz dwa programy (zakodowane na stronie 437 kodu IBM )
☻☻Program A
i
☺Program B
Znaki znajdujące się w dokładnie jednym programie
☻☺AB
Zatem wynik wynosi 4. Uwaga, która ☻
pojawia się dwa razy w pierwszym programie, ale jest liczona tylko raz.
Twoim celem jest uzyskanie jak najwyższego wyniku, najwyższy możliwy wynik to 256.
Oto program oceniania, który działa dla programów zakodowanych w ASCII.
Zastrzeżenia
Każdy bajt w obu programach powinien mieć możliwość zastąpienia innym bajtem, co powoduje, że albo program się kompiluje do innego wyniku, albo nie kompiluje się razem. Usunięcie dowolnego bajtu powinno zrobić to samo.
Możesz używać dowolnych flag kompilacji, o ile oba programy działają z tymi samymi flagami.
Wynikowa kompilacja powinna być statyczna (tj. Nie powinna się zmieniać w zależności od uruchomienia), jeśli wyniki różnią się w zależności od maszyny, wskazują maszynę, na której ma ona działać.
Dane wyjściowe kompilacji powinny być bajtowe dla bajtu identycznego, a nie „równoważnego” lub „wystarczająco podobnego”.
Dane wyjściowe kompilacji powinny być niepuste
Ostrzeżenia / błędy nie muszą być takie same między kompilacjami
Jeśli programy lub kompilacja zawierają znaki niedrukowalne, koniecznie dołącz zrzut heksowy. Chociaż nie jest to technicznie wymagane.
źródło
abcdefghijqlmnop...
używającej ponad 20 unikalnych znaków. Czy to jest dozwolone?Code-Bowling
pytanie!Odpowiedzi:
Perl, wynik 254 + 2 = 256
Oto zrzut heksowy jednego programu:
a oto inny program:
Perl zwykle nie myśli o skompilowanym języku, ale tak jest; najpierw jest kompilowany do kodu bajtowego, a następnie wykonywany jest kod bajtowy. Możesz zastosować filtr do kodu bajtowego (np. Aby go zrzucić, zamiast uruchamiać program), korzystając z
-MO
opcji. Oba te programy kompilują się w następujący kod bajtowy (zdemontowany przy użyciu-MO=Terse
):Wyjaśnienie
Perl zastępuje wszystkie instrukcje bez skutku (takie jak literały łańcuchowe same w sobie) zakodowaną na stałe instrukcją „instrukcja bez efektu” w wynikowym kodzie bajtowym, więc oba programy kompilują się do tego samego. Jeśli chodzi o zastępowanie znaków, zastąpienie większości znaków z programu 1 apostrofami spowoduje, że kompilacja nie powiedzie się (lub zastąpi apostrofy
0
). W programie 2 zastąpienie dowolnego znakuc
spowoduje, że program się nie skompiluje (jak\c
argument).Jeśli chodzi o usuwanie znaków, pierwsza wersja tej odpowiedzi była wcześniejsza niż „reguła hartowania radiacyjnego” (że usunięcie dowolnego znaku musi zmienić zachowanie programu). Ta zaktualizowana, utwardzana promieniowaniem wersja działa za pomocą sumy kontrolnej; jeśli usunięcie znaku nie spowoduje bezpośredniego błędu składniowego, kod zostanie skompilowany w wywołanie nieistniejącej funkcji
x
. Kompilator Perla nie optymalizuje wywołania w przypadku, gdy zostało wykonane (i generalnie nie wydaje się świadomy, że funkcja nie istnieje), a zatem wynik jest inny. Jednak stały folder Perla jest w stanie zobaczyć, że niezmutowany program jest pojedynczą instrukcją bez żadnego efektu, a zatem optymalizuje całość do pojedynczej instrukcji, jak poprzednio.Pierwotnie źle odczytałem pytanie jako liczące tylko unikalne znaki z jednego programu i próbowałem je zoptymalizować. Oczywiście program 2 musi zawierać co najmniej jeden znak, aby wygenerować kod operacji „instrukcja bez efektu”, co oznacza, że najlepszy możliwy wynik w jednym programie to 255. Nie znalazłem jeszcze sposobu na włączenie odwrotnego ukośnika w programie 1 w taki sposób, że następująca po niej postać nie może zostać zastąpiona w sposób powodujący uszkodzenie programu, ale nie zaskoczyłoby mnie, gdyby było to możliwe (prowadząc do wyniku 255 + 1 = 256 ).
źródło
C 231
Program A
Wiele materiałów niedrukowalnych powyżej. Oto zrzut heksowy xxd:
Program B
Kompilują się one dokładnie w tym samym kodzie obiektowym. GCC osadza nazwę pliku w kodzie obiektu, więc musisz nadać plikom tę samą nazwę (w różnych katalogach).
Martwiłem się, że fakt, że nie ma żadnych odwołań,
i
może spowodować, że kompilator całkowicie zoptymalizuje tę zmienną, ale myślę, że uczynienie z niej globalnej gwarancji, że będzie obecna w obiekcie. Można to zweryfikować poprzez kontrolę wygenerowanego zestawu:Zauważ, że w programie B (większość) wartości char podane są ósemkowo. Można je również podawać w systemie dziesiętnym, ale używając liczb ósemkowych uzyskujemy kilka dodatkowych znaków -
8
i9
- w zestawie różnic.GCC nie lubi CR, LF i (z oczywistych powodów) znaków NUL w pojedynczych cudzysłowach
''
.Wypróbuj online i zdobądź punkty .
źródło
char
niejawnaint
, ze szkodą dla wyniku.Python, wynik
16262728Unikalne postacie:
-+;132547698<ACBEDFOXabopsx|
Oblicz wynik
Program 1:
W programie 1 jest 5 spacji w pozornie pustej linii.
Program 2:
Znaleziono pomoc w kodzie źródłowym optymalizatora wizjera .
Testowane przy pomocy tego skryptu pomocniczego: Wypróbuj online!
źródło
Python 3.6,
2 3 56Program 1:
Program 2:
Python zwykle nie jest kompilowany, ale kompiluje kod źródłowy do plików pyc. Co najważniejsze, takie kompilowanie obejmuje przepustkę optymalizacyjną, która zmienia „1111 + 4168” na 5279. Podkreślenia służą dwóm celom: jednym z nich jest dodanie jednego do partytury, a drugim zachowanie długości, która jest przechowywana w pyc nagłówek taki sam. Wszystkie przypisania zmiennych inne niż „x” mają zachować
co_consts
odpowiednią kolejność. Nax*x
końcu służy do utrzymaniaco_stacksize
tego samego.źródło
compile
funkcji, która nie dodaje nagłówka. Plik mtime i nazwa pliku dotyczy odnoszą się tylko do nagłówkaos.utime
funkcjiFASM, 254
nie 0x00 i 0x1A, ponieważ fasm nie obsługuje dwóch symboli
źródło