To było zabawne wyzwanie, aby popracować między świętami Bożego Narodzenia. Dziękujemy za wysłanie wiadomości! Gra w golfa była interesująca, ponieważ specyfikacja jest pełna wyjątków i specjalnych przypadków, które wymagały wielu warunków if. Ponadto, chociaż tym razem nie musiałem konwertować na i od dziesiętnego, potrzebowałem rodzaju „max”, aby określić największą liczbę cyfr w każdej liczbie i największą wartość cyfr w każdym miejscu.
Pierwsza wersja tego pliku to 4844 bajty, aby dać wyobrażenie o tym, ile grałem w golfa.
Program oczekuje danych wejściowych jako rozdzielonej przecinkami listy liczb całkowitych. Bez spacji i znaków nowej linii. Korzystanie z nich spowoduje niezdefiniowane zachowanie.
„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ „” „„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ” „” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „„ ” „„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „„ ” „” „” „” „” „” „” „” „” „” „” „” „” „„ ”„ „” „” „” „„ ” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „„ ”„ ”„ ”„ „” „” „” „” „” „„ ”„ „” „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „” „” „” „„ ”„ „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ „” „” „” „” „” „” „” „” „„ ”„ ”„ „” „” „” „” „” „” „„ ”„ „” „„ ”„ „” „” „” „” „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ „” „” „”„” „” „” „” „” „” „„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ „” „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ „ „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ „” „” „” „”„” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ „” „” „” „” „” „„ ”„ ”„ ”„ „” „” „” „” „„ ”„ „” „” „„ ”„ ”„ ”„ ”„” „” „” „” „„ ”„ ”„ ”„ „” „” „” „„ ”„ „” „„ ”„ ”„ ” „” „” „” „” „” „” „” „„ ”„ ”„ „” „„ ”„ „” „” „” „„ ”„ ”„ ” „” „” „” „” „” „” „„ ”„ „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ „” „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „” „”„” „” „” „” „” „„ ”„ „” „” „” „” „” „„ ”„ „” „” „” „” „” „” „” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „„ ”„ ”„ ”„ ”„ „” „” „” „” „„ ”„ „” „” „” „” „”„” „” „” „” „„ ”„ ”„ ”„ „” „” „” „” „„ ”„ „” „” „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ” „” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ „” „” „”„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „” „” „” „” „” „” „„ ”„ „” „” „” „” „” „„ ”„ „” „„ ”„ ”„ „” „” „”„” „” „” „” „„ ”„ ”„ ”„ „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ „” „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „” „” „” „” „” „” „” „” „” „” „” „” „” „” „” „” „” „” „„ ”„ „” „” „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „” „” „” „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ „” „” „”„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „” „„ ” „” „„ ”„ ”„ ”„ „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ „” „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „” „„ ” „” „” „” „” „„ ”„ ”„ ”„ „” „” „” „” „„ ”„ „” „” „„ ”„ ”„ ”„ ”„” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „ „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „” „” „” „” „” „”„” „” „” „” „„ ”„ „” „” „” „” „” „” „„ ”„ „” „” „” „” „” „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „” „” „” „” „” „„ ”„ ”„ „” „” „” „” „„ ”„ „” „„ ”„ ”„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ „” „” „” „” „„ ”„ „” „” „” „” „„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „„ ”„ ”„ ”„ „” „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”
Wyjaśnienie
Pokażę ci, jak działa program, pokazując, jak przetwarza określone dane wejściowe 202,100,1
.
Na początku konstruujemy kilka wartości, które będą nam potrzebne później - głównie kody ASCII znaków, które wyprowadzimy.
Jak widać '8'
i '.'
są już dostępne. '|'
, jednak tak naprawdę wynosi 124, a nie 14. Używamy pętli while, aby dodać dwukrotnie wartość tymczasową w gnieździe nr 1, aby uzyskać 124 (czyli 14 + 55 × 2, ponieważ pętla while działa dla 56-1 = 55 iteracje). Oszczędza to niektóre bajty, ponieważ duże literały całkowite, takie jak 124, są naprawdę długie. Na poniższym diagramie pokazuję lokalizację każdej zmiennej używanej przez program.
Następnie chcemy wprowadzić wszystkie znaki i zapisać je na taśmie, zaczynając od komórki nr 12 ( p jest do tego wskaźnikiem uruchomionym). Jednocześnie chcemy wiedzieć, jak najdłuższa jest liczba (ile cyfr). Aby to osiągnąć, utrzymujemy sumę bieżącą w jednostajnym ruchu w lewo, zaczynając od komórki # -1 (używamy q jako wskaźnika). Po pierwszej liczbie wejściowej ( 202
) taśma wygląda teraz tak:
Zauważysz, że liczby są wyłączone o 4. Cóż, kiedy je wprowadzamy, są to ich wartości ASCII, więc są „wyłączone” o 48, a przecinek wynosi 44. Dla każdego znaku kopiujemy 46 z '.'
do r, a następnie odejmij go za pomocą pętli while (która odejmuje 45), a następnie dodajemy 1. Robimy to, aby przecinek (nasz separator) wynosił 0, więc możemy użyć warunkowego rozpoznania go.
Zauważysz również, że zostawiamy komórkę nr 11 na 0. Potrzebujemy tego, aby rozpoznać granicę pierwszej liczby.
Następną postacią będzie przecinek, więc przechowujemy 0 na # 15, ale oczywiście tym razem nie przesuwamy q . Zamiast tego ustawiamy q z powrotem na 0 i zaczynamy „nadpisywać” jedynki, które już umieściliśmy.
Po przetworzeniu wszystkich pozostałych znaków otrzymujemy:
Jak widać, cyfry 1 napisane przez q wskazują teraz (w unary) długość najdłuższej liczby.
Teraz używamy pętli while, aby przesunąć q na samą lewą stronę, a następnie umieścić tam inny wskaźnik, który nazwiemy r2 . Cel r2 stanie się jasny później.
W tym miejscu pozwól mi wyjaśnić terminologię, której będę używać w tym miejscu.
- Przez liczbę rozumiem jedną z liczb wejściowych oddzielonych przecinkami. W naszym przykładzie są to 202, 100 i 1.
- Przez cyfrę rozumiem pojedynczą cyfrę w określonej z liczb. Pierwszy numer ma 3 cyfry.
- Przez miejsce rozumiem jedno miejsce, dziesiątki miejsca, setki miejsc itp. Więc jeśli powiem „cyfry w bieżącym miejscu”, a bieżące miejsce to jedyne miejsce, cyfry to 2, 0 i 1 w tym miejscu zamówienie.
Teraz wracamy do naszego regularnego programowania. Cała reszta programu to duża pętla, która przesuwa q do przodu, aż osiągnie komórkę # 0. Każda z komórek po drodze reprezentuje miejsce, z tymi po skrajnie prawej stronie, a q rozpocznie się od najbardziej znaczącego. W naszym przykładzie jest to setki miejsc.
Kontynuujemy, zwiększając liczbę punktów q w komórce (czyli * q ).
Jesteśmy teraz na „etapie 2” dla setek miejsc. Na tym etapie dowiemy się, jaka jest największa cyfra spośród wszystkich cyfr w setkach miejsc. Używamy do tego tej samej jednostkowej sztuczki liczenia, z tym wyjątkiem, że wskaźnik nazywa się r, a wskaźnik r2 oznacza jego pozycję początkową, do której musimy go resetować za każdym razem, gdy przechodzimy do następnej liczby.
Zacznijmy od pierwszego numeru. Zaczynamy od ustawienia p na 11 (zakodowana pozycja początkowa wszystkich liczb). Następnie używamy pętli while, aby znaleźć koniec liczby i ustawiamy tam p2 , aby zaznaczyć pozycję. Jednocześnie ustawiamy q2 na 0:
Nie rozpraszaj się faktem, że q2 wskazuje na zmienne. Nie mamy tam wypełnienia pustej komórki, ponieważ możemy wykryć komórkę 0 po prostu dlatego, że jest to zero.
Następnie przeglądamy bieżącą liczbę, zmniejszając jednocześnie p i q2, aż * p wyniesie zero. W każdym miejscu wartość * q2 mówi nam, co musimy zrobić. 1 oznacza „nic nie rób”, więc kontynuujemy. W końcu napotykamy 2 w komórce # −3. Za każdym razem, gdy * q2 nie jest równe 1, q2 jest zawsze równe q .
Jak już wspomniałem, etap 2 to „określenie największej cyfry w tym miejscu”. Więc ustawiamy r na r2 , używamy pętli while, aby zmniejszać * p i przesuwamy r w lewo i wypełniamy taśmę 1s, a następnie używamy kolejnej pętli while, aby przesuwać r z powrotem w prawo i zwiększać * p ponownie, aby przywrócić wartość. Pamiętaj, że pętla co chwilę działa dla jednej iteracji mniej niż wartość, na której ją używamy; z tego powodu liczba zapisanych 1s będzie o 3 więcej (zamiast 4 więcej) niż wartość cyfr, a końcowa wartość przechowywana z powrotem w * p będzie o 2 więcej. W ten sposób skutecznie zmniejszono * p o 2.
Następnie ustawiamy p na wartość p2, a następnie robimy to wszystko ponownie. Po raz drugi ustaw q2 na 0, znajdź koniec numeru, przesuwając p w prawo, a następnie przejdź przez cyfry tego numeru, zmniejszając jednocześnie p i q2 . Po raz kolejny napotkamy 2 w komórce # −3 i napiszemy tyle 1s z * r .
W przypadku trzeciej liczby nie robimy nic, ponieważ nie ma setek miejsc (więc q2 nigdy nie osiąga q ), ale to jest w porządku, ponieważ nie wpływa to na obliczenie maksymalnej wartości cyfr.
Ustawiliśmy również komórkę * (r - 4) , którą zaznaczyłem tutaj nieoznaczoną strzałką, na 1 (mimo że jest już na 1). Nie powiem ci jeszcze dlaczego, ale może już zgadłeś?
Następny przyrost * q przenosi nas do etapu 3, czyli „odejmij cyfrę maksymalną od wszystkich cyfr w bieżącym miejscu”. Tak jak poprzednio, resetujemy p do 11 i q2 do 0, a następnie przechodzimy przez wszystkie liczby, tak jak zrobiliśmy to w poprzednim etapie; z wyjątkiem tego czasu * q = 3 zamiast 2. Za każdym razem, gdy q2 spotyka q, a p znajduje się w setkach miejsc, używamy pętli while do zmniejszenia * p tyle razy, ile jest 1s w bloku po lewej stronie * r2 (5 w naszym przykładzie) przy użyciu rjako wskaźnik biegu. Faktycznie zmniejszamy go jeszcze raz, aby największa cyfra kończyła się na -2, z powodu, który stanie się później jasny:
Po przetworzeniu wszystkich liczb jesteśmy teraz na końcu etapu 3. Tutaj wykonujemy dwie osobliwe rzeczy.
- Najpierw odejmujemy również rozmiar bloku r (plus 1) od * q , ale używając wskaźnika r2 , który pozostawia go po lewej stronie. * q staje się w ten sposób ujemny. W naszym przypadku r- blok ma pięć 1, więc * q staje się −3.
- Po drugie, ustawiamy zmienną na niezerową wartość, aby wskazać, że wchodzimy teraz w etap wyjściowy. (Technicznie fakt, że * q jest ujemny, wskazuje już na stopień wyjściowy, ale jest to zbyt trudne do sprawdzenia, stąd dodatkowa zmienna).
Teraz rozumiesz, że ciągle przeglądamy liczby, znajdujemy bieżące miejsce (wskazane przez wartość inną niż 1 * q ) w obrębie każdej liczby i robimy coś w zależności od wartości * q . Widzimy, że * q jest najpierw zwiększane do 2 (= oblicz maksymalną wartość cyfry), a następnie 3 (odejmuj maksymalną wartość cyfry od każdej cyfry w tym miejscu), a następnie odejmujemy od niej, aby była ujemna. Stamtąd będzie rosnąć, aż osiągnie 1, przywracając w ten sposób wartość oznaczającą „nic nie rób”. W tym momencie przechodzimy do następnego miejsca.
Teraz, gdy * q jest ujemne, wysyłamy dane wyjściowe. * q ma dokładnie prawidłową wartość, dzięki czemu wyprowadzimy odpowiednią liczbę wierszy znaków, zanim osiągnie 1; jeśli największa cyfra to 2, musimy wyprowadzić 3 wiersze. Zobaczmy, co się stanie przy każdej wartości * q :
- * q = -2:
- W przypadku pierwszej liczby * p wynosi -2, co oznacza, że musimy wyprowadzić a
'.'
(kropkę) lub a ':'
(dwukropek). Decydujemy, które patrząc na q : jeśli jest to -1, jesteśmy w jednym miejscu, więc wypisz a ':'
(które obliczamy jako '8'
+2), w przeciwnym razie a '.'
.
- Dla drugiej liczby * p wynosi −3. Wszystko, co nie jest -2 oznacza, że wyprowadzamy
'|'
(potok), a następnie zwiększamy wartość. W ten sposób osiągnie -2 we właściwym miejscu, a następnie wyprowadzimy '.'
s / ':'
s dla reszty tej cyfry.
- W każdym przypadku ustawiamy również zmienną pd na 0 przed przetworzeniem liczby i ustawiamy pd (= „drukowane”) na wartość niezerową, aby wskazać, że wydrukowaliśmy znak.
- W przypadku trzeciej liczby przetwarzanie nie występuje, ponieważ trzecia liczba nie ma setek miejsc. W tym przypadku pd będzie nadal wynosić 0 po przetworzeniu liczby, co oznacza, że nadal musimy wyprowadzić a
'|'
(ale tylko wtedy , gdy out jest niezerowy, ponieważ w przeciwnym razie nadal jesteśmy na etapie 2 lub 3).
- Po przetworzeniu wszystkich liczb, jeśli out jest niezerowy, wypisz nowy wiersz. Zauważ, że potrzebujemy zmiennej out , abyśmy nie wypisywali nowej linii na etapie 2 lub 3.
- * q = -1: Tak samo jak poprzednio, z tym wyjątkiem, że * p wynosi -2 dla obu pierwszych dwóch liczb, więc oba wyprowadzają a
'.'
(a trzecie wyprowadza a'|'
jak poprzednio).
- * q = 0: Gdy * q wynosi 0, oznacza to „nic nie rób, jeśli jesteśmy w jednym miejscu, w przeciwnym razie wypisz wiersz
'|'
s niezależnie od * p ”. W ten sposób uzyskujemy dopełnienie między cyframi.
Teraz zwiększamy q, aby przejść do następnego miejsca, miejsca dziesiątek i zwiększamy * q tam. Na początku drugiego etapu taśma wygląda następująco:
Następnie wykonujemy etap 2 tak jak poprzednio. Pamiętaj, że to skutecznie odejmuje 2 od każdej cyfry w tym miejscu, a także pozostawia niezmienną liczbę pozostawioną z * r2 wskazującą maksymalną cyfrę. Pozostawiamy poprzedni numer jednostkowy w spokoju i po prostu wyciągamy taśmę w lewo; „wyczyszczenie” kosztowałoby tylko niepotrzebny dodatkowy kod. Kiedy skończymy i zwiększamy * q , na początku etapu 3 taśma jest teraz:
Właściwie to kłamstwo. Pamiętasz wcześniej, gdzie powiedziałem, że ustawiliśmy * (r - 4) na 1 i nie powiedziałem ci dlaczego? Teraz powiem ci dlaczego. Dotyczy to przypadków takich jak ten, gdzie największa cyfra to w rzeczywistości 0, co oznacza, że wszystkie cyfry w tym miejscu to 0. Ustawienie * (r - 4) , wskazane przez nieznakowaną strzałkę powyżej, do 1 powoduje zwiększenie liczby jednorzędowej o 1, ale tylko w tym szczególnym przypadku. W ten sposób udajemy, że największą cyfrą jest 1, co oznacza, że wyprowadzimy jeden dodatkowy wiersz.
Po etapie 3 (odejmij cyfrę maksymalną od wszystkich cyfr w bieżącym miejscu), włączając dodatkowy krok, który powoduje, że * q jest ujemny, taśma wygląda następująco. Ostatnim razem najwyższa cyfra była reprezentowana przez −2 w bloku * p , ale tym razem wszystkie są −3, ponieważ w rzeczywistości wszystkie są zerami, ale udajemy, że maksymalna cyfra to 1.
Zobaczmy teraz, co się stanie, gdy * q przejdzie w kierunku 1:
- Gdy * q = -1, wszystkie * p są równe -3, co oznacza, że wyprowadzamy
'|'
s i zwiększamy je.
- Kiedy * q = 0, wyprowadzamy,
'|'
ponieważ zawsze tak robimy, gdy * q = 0, niezależnie od * p .
W ten sposób otrzymujemy dwa rzędy rur.
Na koniec przenosimy * q na miejsce jednego. Ten staje się interesujący, ponieważ musimy wypisać ':'
s, jeśli rzeczywista cyfra jest inna niż 1, ale '8'
jeśli to 1. Zobaczmy, jak działa program. Najpierw zwiększamy * q, aby rozpocząć Etap 2:
Po etapie 2 („oblicz maksymalną wartość cyfr”) pozostaje nam to:
Po etapie 3 („odejmij maksymalną wartość cyfr od wszystkich cyfr w bieżącym miejscu”) taśma wygląda następująco:
Teraz przejdźmy kolejno do każdej iteracji * q :
- * q = -2:
- Pierwsza liczba: już na -2, więc wypisz a
':'
(zamiast a, '.'
ponieważ q = -1).
- Druga liczba: at -4, więc wypisz a
'|'
i przyrost.
- Trzecia liczba: przy -3, więc wypisz a
'|'
. Jednak tym razem zamiast inkrementacji uruchamiany jest specjalny przypadek. Tylko jeśli wyprowadzamy ostatnie miejsce ( q = -1) i znajdujemy się w tym przedostatnim rzędzie ( * q = -2), a cyfra to w rzeczywistości 1 ( * p = -3) , wtedy zamiast zwiększany do -2, że ustawione na -1. Innymi słowy, używamy -1 jako specjalnej wartości, aby wskazać, że w następnej iteracji będziemy musieli wyprowadzać dane '8'
zamiast ':'
.
- * q = -1:
- Pierwsza liczba: już na -2, więc wypisz a
':'
.
- Druga liczba: na -3, więc wyjście A
'|'
. Warunek specjalny nie jest uruchamiany, ponieważ * q nie jest już równe -2. Dlatego przyrost.
- Trzecia liczba: at -1, więc wyjście
'8'
.
- * q = 0: Zwykle wypisywaliśmy tutaj wiersz wypełnienia
'|'
s, ale w szczególnym przypadku, gdy jesteśmy w jednym miejscu ( q = -1), pomijamy to.
Następnie q jest zwiększane do 0, a duża pętla while kończy się.
Teraz wiesz, jak 202,100,1
działa takie wejście . Jest jednak jeszcze jeden szczególny przypadek, którego jeszcze nie omówiliśmy. Być może pamiętasz, że podczas przetwarzania ostatniego miejsca, gdy * p było −3, ustawiliśmy go na −1 dla 1
(zamiast zwiększania do −2), aby następna iteracja wygenerowała '8'
zamiast niego. Działa to tylko dlatego, że mamy iterację, w której * p wynosi −3 i podejmujemy decyzję, czy należy ją zwiększyć, czy ustawić na −1. My nie mają takiej iteracji jeśli wszystkie cyfry w miejscu z nich to 0 lub 1. W takim przypadku wszystkie * P wartości dla 1s by zacząć się w -2; nie ma możliwości wyboru ustawienia na -1zamiast zwiększać ją z -3 . Z tego powodu w etapie 3 występuje inny warunek specjalnej obudowy („odejmij maksymalną liczbę od każdej cyfry w bieżącym miejscu”). Twierdziłem, że po odjęciu wartości maksymalnej cyfry od każdej cyfry (w tym momencie cyfra maksymalna wynosi -1), po prostu ją zmniejszamy jeszcze raz, ale tak naprawdę istnieje warunek, który wygląda następująco:
Jeśli cyfra, na którą patrzymy, jest równa maksymalnej cyfrze w tym miejscu ( * p = -1), a to miejsce to jedyne miejsce ( q = -1), a maksymalna cyfra to 1 ( * (r + 5) = 0, tzn. Jednostkowy blok po lewej stronie ma tylko 5 komórek długości, tylko wtedy zostawiamy * p na -1, aby wskazać, że jedyna iteracja wyjścia musi dać an '8'
. We wszystkich innych przypadkach ponownie to zmniejszamy.
Gotowy. Szczęśliwego Nowego Roku!
Edycja 1 (3183 → 3001): Trochę golfa w Szczęśliwego Nowego Roku! Udało mi się całkowicie pozbyć zmiennych p2 i r2 ! p pędzi teraz w tę iz powrotem, aby znaleźć początek i koniec liczb, ale wydaje się, że kod jest krótszy. Próbowałem również pozbyć się q2 , ale nie mogłem skrócić kodu w ten sposób.
Znalazłem też kilka innych miejsc, w których mogłem zastosować typowe Nieczytelne sztuczki golfowe, takie jak ponowne użycie ostatniej wartości pętli while. Podam przykład zamiast
while *(++p) { 1 } // just increment p until *p is 0; the 1 is a noop
if (pd) { x } else { y } // where pd is a variable
Mogę zapisać '""""
(zrób pierwszy, potem drugi) i '"""
(stałą 1), pisząc to w sposób podobny do
if (while *(++p) { pd }) { x } else { y }
Oczywiście działa to tylko wtedy, gdy wiem, że pętla while będzie działała przez co najmniej jedną iterację, ale jeśli tak, jej wartością zwracaną jest pd, więc mogę użyć tego jako warunku dla if.