Kilka wskazówek tutaj:
Stałe:
Strona stałych Esolangs zawiera niezwykle przydatną listę najkrótszych sposobów tworzenia określonych wartości. Uważam, że sprawdzam tę stronę co najmniej dwa razy na program.
Początek wszystkiego:
+++[[<+>>++<-]>]
Spowoduje to ustawienie taśmy w formacie 3 * n ^ 2, który wygląda
3 6 12 24 48 96 192 128 0 0 '
Dlaczego to takie ważne?
Zejdźmy na dół listy:
- 3 i 6 są nudne
- 12: Blisko 10 (nowa linia) lub 13 (powrót karetki). Może być również użyty do licznika dla 0-9
- 24: Blisko 26, liczba liter w alfabecie
- 48: ASCII dla
0
- 96: Blisko 97, ASCII dla
a
- 196 i 128: 196-128 = 64, blisko 65, ASCII dla
A
.
Na podstawie tego jednego algorytmu jesteśmy na początku praktycznie każdej sekwencji w zakresie ASCII, wraz z licznikiem dla każdej i nowej linii w zasięgu ręki.
Praktyczny przykład:
Drukowanie wszystkich wielkich i małych liter oraz cyfr.
Z algorytmem:
+++[[<+>>++<-]>]<<[-<->]<<<<++[->>+.>+.<<<]<--[>>.+<<-]
Bez:
+++++++++++++[->+++++++>++>+++++>++++>+<<<<<]>+++++>[-<+.>>.+<]>>---->---[-<.+>]
Większość bajtów spędzamy na inicjalizacji taśmy w drugim przykładzie. Niektóre z nich zostały zrównoważone przez dodatkowe ruchy w pierwszym przykładzie, ale ta metoda ma wyraźnie tę zaletę.
Kilka innych interesujących algorytmów w tym samym stylu:
3 * 2 ^ n + 1:
+++[[<+>>++<-]+>]
Tape: 4 7 13 25 49 65 197 129 1 0'
Powoduje to przesunięcie wartości o 1, co pozwala osiągnąć kilka rzeczy. Powoduje to, że 12 jest znakiem powrotu karetki, 64 to faktyczny początek wielkiej litery, a 24 bliżej 26.
2 ^ n:
+[[<+>>++<-]>]
Tape: 1 2 4 8 16 32 64 128
Ponieważ 64 jest dobre dla wielkich liter, 32 to ASCII dla spacji, a 128 może być użyte jako licznik dla 26 (130/5 = 26). Może to zaoszczędzić bajty w pewnych sytuacjach, w których cyfry i małe litery nie są potrzebne.
Wybierz implementację, która pasuje do pytania:
- Komórki ujemne są prawie zawsze przydatne i nie ma powodu, aby ich unikać (chyba że nie zmienia to liczby bajtów)
- Prawie dokładnie to samo z zawijaniem komórek, tym bardziej, że wiele stałych używa zawijania.
- Arbitralne rozmiary komórek są przydatne do nieskończonych sekwencji matematycznych, takich jak nieskończone obliczanie sekwencji Fibonacciego (
+[[-<+>>+>+<<]>]
) lub przetwarzanie większych / ujemnych liczb. Minusem jest to, że na niektóre typowe metody, takie jak [-]
i [->+<]
nie można polegać, na wypadek gdyby liczba była ujemna.
- EOF jako 0, -1 lub bez zmian. Zazwyczaj preferowane jest 0, ponieważ można zapętlać całe dane wejściowe bez dodatkowych kontroli. -1 jest przydatne przy zapętlaniu struktur tablicowych. Nie znalazłem jeszcze zastosowania bez zmian :(.
Śledź, co się dzieje do cholery:
Przez cały czas powinieneś komentować, gdzie powinien znajdować się wskaźnik w stosunku do otaczających go danych, i upewnij się, że znasz zakres możliwych wartości każdej komórki. Jest to szczególnie ważne, gdy podzielisz wskaźnik przed pętlą, ponieważ później będziesz chciał ponownie połączyć dwie możliwości.
W dowolnym momencie mój kod jest zaśmiecony komentarzami w każdej innej linii, które wyglądają tak:
*0 *dat a_1 ? 0' !0 0*
or
*0 *dat 0' ap1 0 !0 0*
Dodatkową radą jest nadanie symbolom specjalnego znaczenia. W powyższym przykładzie, '
gdzie jest wskaźnik, *
oznacza powtórzenie w tym kierunku, ?
oznacza komórkę o nieznanej wartości, !0
oznacza komórkę niezerową, _
jest substytutem -
i p
jest substytutem +
. or
oznacza, że taśma może wyglądać jak jedno z przedstawień i musi być traktowana jako taka.
Twój schemat symboli niekoniecznie musi być taki sam jak mój (który ma kilka wad), po prostu musi być spójny. Jest to również niezwykle przydatne podczas debugowania, ponieważ można uruchomić go do tego momentu i porównać rzeczywistą taśmę z tym, co powinieneś mieć, co może wskazać potencjalne wady w kodzie.