Code golf zawsze zawiera odpowiedzi, które mniej lub bardziej naginają reguły, przełamując ograniczenia, które pretendenci wzięli za pewnik lub po prostu o tym nie pomyśleli i nie wymienili ich w przepisach. Jedną z tych interesujących luk jest możliwość wyjścia więcej niż wymaga wyzwanie, aby uzyskać lepszy wynik.
Biorąc to do końca, możemy napisać uniwersalny koder solvera do golfa, który drukuje pożądane dane wyjściowe - jeśli nie przejmujesz się, że może to potrwać wieki i wyświetla wiele innych rzeczy przed i po nim.
Wszystko, co musimy wygenerować, to sekwencja, która z pewnością zawiera wszystkie możliwe podsekwencje. Dla tego kodu golfowego będzie to sekwencja Ehrenfeucht-Mycielski :
Sekwencja zaczyna się od trzech bitów 010; każda kolejna cyfra jest tworzona przez znalezienie najdłuższego sufiksu sekwencji, który również pojawia się wcześniej w sekwencji, i uzupełnienie bitu po ostatnim wcześniejszym pojawieniu się tego sufiksu.
Każda skończona podsekwencja bitów zachodzi w sposób ciągły, nieskończenie często w obrębie sekwencji
Pierwsze kilka cyfr sekwencji to:
010011010111000100001111 ... (sekwencja A038219 w OEIS ).
Łącząc 8 bitów sekwencji w bajt, otrzymamy wyjście ASCII, które możemy wyprowadzić na ekran lub do pliku i które zawiera każde możliwe skończone wyjście . Program wyświetli fragmenty pi, teksty „Never will give you you” , jakąś fajną grafikę ASCII, własny kod źródłowy i wszystko inne, co chcesz, aby powstało.
Do testowania poprawności, oto skróty dla pierwszych 256 bajtów sekwencji:
MD5: 5dc589a06e5ca0cd9280a364a456d7a4
SHA-1: 657722ceef206ad22881ceba370d32c0960e267f
Pierwsze 8 bajtów sekwencji w zapisie szesnastkowym to:
4D 71 0F 65 27 46 0B 7C
Zasady:
Twój program musi wypisać sekwencję Ehrenfeucht-Mycielski (nic więcej), łącząc 8 bitów w bajt / znak ASCII.
Zwycięża najkrótszy program (liczba znaków). Odejmij 512 od liczby znaków, jeśli uda ci się wygenerować sekwencję w czasie liniowym na wygenerowany bajt .
Odpowiedzi:
C, –110 znaków
Ta wersja programu wykorzystuje algorytm liniowego środowiska wykonawczego do wygenerowania sekwencji. Odejmowanie 512 z 402 znaków w programie daje w sumie ujemną 110.
Zgodnie z problemem program działa w nieskończonej pętli, co wymaga dużej alokacji pamięci, a użycie
realloc()
do zachowania ciągłości sekwencji może przyczynić się do fragmentacji sterty. Możesz poprawić wykorzystanie pamięci programu, zastępująccalloc(7,8)
w pierwszym wierszu znakiemcalloc(1,sizeof*v)
. Pomoże to zwłaszcza na 32-bitowej maszynie, gdzie 56 jest prawdopodobnie zbyt duże dwa razy.Kod jest w pewnym sensie nieczytelny i nie w interesujący sposób; za to przepraszam. Szczerze mówiąc, nawet wersja bez golfa nie jest strasznie jasna:
(Niegolfowany kod powyżej opiera się na kodzie napisanym przez Grzegorza Hermana i Michaela Soltysa, o których mowa w opisie problemu oraz ze strony głównej Soltysa ).
Dzięki @schnaader i @res za zgłoszenie błędu w początkowej wersji.
źródło
malloc
wersje z golfem, bez golfa i zmodyfikowane zatrzymują wyjście po około 10000 bajtach i kontynuują przydzielanie pamięci,prog > out.dat
natychmiast powodują awarię przy zużyciu pamięci tylko ~ 700 KB. Jeśli wstawięprintf("\n%i\n", size);
porealloc
, największą wartością wyjściową jest4
. System: Windows 7 Prof. 64-bit, 4 GB pamięci RAM, GCC 4.6.1Ruby,
10910410194 znakówImplementacja w Ruby przy użyciu wyrażeń regularnych do wyszukiwania sufiksów. Ponieważ zabranie pamięci zajmuje dużo czasu, program musi zostać zakończony przez użytkownika.
Edytować: Właśnie zauważyłem, że wystarczy zacząć od sekwencji
0
.Edycja 2: Propozycja res zapisuje 2 znaki, niektóre inne, ponieważ nie musimy wcześniej wycinać ani jednego bajtu
pack
.źródło
s=(s[/(.*).*\1/][/.#{$1}/]<?1??1:?0)+s
spowoduje zapisanie kolejnych dwóch znaków.?C
?Perl, 95 znaków
Na początku miałem w połowie przyzwoitą wersję tego. Potem, gdy grałem w golfa, każda wersja stała się wolniejsza. Coraz wolniej.
Pierwsze trzy znaki (
$|=
) nie są konieczne, ściśle mówiąc ... ale bez tego zwykle trzeba by czekać, aż skrypt zakończy generowanie pełnych 4096 bajtów, zanim zobaczysz wynik. A to zajmie godziny. Może stulecia; Nie jestem pewny. Czy wspomniałem, że wydajność tego programu pogarsza się z czasem? Z tego powodu poczułem się zmuszony do włączenia ich do hrabstwa.Z drugiej strony, ten skrypt ma jeden z najbrzydszych wyrażeń regularnych, jakie kiedykolwiek stworzyłem, więc myślę, że jestem z niego dumny.
źródło