Acc !! , 129 bajtów
Nieźle jak na dość gadatliwą Tarpit Turinga ...
N
Count i while _%128-9 {
Count x while _/128%2 {
Write 40
_+128
}
Write _%128
_+128-_%128+N
}
Count j while _/256-j {
Write 41
}
(Tak, wszystkie te białe znaki są obowiązkowe).
Uwaga: z powodu ograniczeń wejściowych Acc !! , nie można odczytać dowolnego ciągu znaków bez ogranicznika końcowego. Dlatego ten program oczekuje, że wejście (standardowe wejście) jest ciągiem, po którym następuje znak tabulacji.
Acc !! ?
To język, który stworzyłem, który wydaje się być bezużyteczny . Jedynym typem danych są liczby całkowite, jedyną konstrukcją przepływu sterującego jest Count x while ypętla, a jedynym sposobem przechowywania danych jest pojedynczy akumulator _. Dane wejściowe i wyjściowe są wykonywane po jednym znaku za pomocą wartości specjalnej Ni Writeinstrukcji. Pomimo tych ograniczeń jestem pewien, że Acc !! jest ukończony przez Turinga.
Wyjaśnienie
Podstawowa strategia w Acc !! programowanie polega na użyciu %dzielenia mod i liczb całkowitych, /aby koncepcyjnie podzielić akumulator, umożliwiając mu przechowywanie wielu wartości jednocześnie. W tym programie wykorzystujemy trzy takie sekcje: siedem bitów najniższego rzędu ( _%128) przechowuje kod ASCII z wejścia; następny bit ( _/128%2) przechowuje wartość flagi; a pozostałe bity ( _/256) policzą liczbę potrzebnych skróconych części.
Wejście w Acc !! pochodzi ze specjalnej wartości N, która odczytuje pojedynczy znak i ocenia na kod ASCII. Każda instrukcja, która składa się wyłącznie z wyrażenia, przypisuje wynik tego wyrażenia do akumulatora. Zaczynamy więc od zapisania kodu pierwszego znaku w akumulatorze.
_%128zapisze ostatnio przeczytaną postać. Tak więc pierwsza pętla działa, gdy _%128-9jest niezerowa - to znaczy, dopóki obecny znak nie będzie tabulatorem.
Wewnątrz pętli chcemy drukować, ( chyba że wykonamy pierwszą iterację. Ponieważ Acc !! nie ma instrukcji if, musimy używać pętli dla warunkowych. Używamy bitu 128 akumulatora _/128%2, jako wartości flagi. Przy pierwszym przejściu jedyną rzeczą w akumulatorze jest wartość ASCII <128, więc flaga ma wartość 0, a pętla jest pomijana. Przy każdym kolejnym przejściu upewnimy się, że flaga ma wartość 1.
Wewnątrz Count xpętli (ilekroć flaga ma wartość 1), piszemy otwarty paren (ASCII 40) i dodajemy 128 do akumulatora, ustawiając w ten sposób flagę na 0 i wychodząc z pętli. Zdarza się to również, aby zwiększyć wartość _/256, której użyjemy jako naszą sumę przybliżeń do wygenerowania.
Bez względu na wartość flagi piszemy najnowszy znak wejściowy, który jest po prostu _%128.
Następne przypisanie ( _+128-_%128+N) robi dwie rzeczy. Po pierwsze, dodając 128, ustawia flagę po raz kolejny przez pętlę. Po drugie, wyzerowuje _%128miejsce, odczytuje inną postać i zapisuje ją tam. Potem zapętlamy.
Kiedy Count ipętla kończy pracę, właśnie odczytaliśmy znak tabulacji, a wartość akumulatora rozkłada się w następujący sposób:
_%128: 9(znak tabulacji)
_/128%2: 1(flaga)
_/256: liczba odczytanych znaków minus 1
(Minus 1 wynika z tego, że dodajemy 128 do akumulatora tylko raz podczas pierwszego przejścia przez główną pętlę.) Wszystko, czego teraz potrzebujemy, to zbliżenia. Count j while _/256-jpętle _/256razy, za 41każdym razem pisząc ścisły paren (ASCII ). Voila!