Jedna linijka kodu do wygenerowania nieskończonego labiryntu

https://xpil.eu/k7c

Całkiem niedawno natknąłem się na jednolinijkowy kod napisany w języku Basic, wersja dla Commodore 64.

Kod generuje nieskończenie duży labirynt zbudowany z prostokątnych segmentów.

Labirynt nie jest "rozwiązywalny" (to logiczne, w końcu jest nieskończony, przynajmniej dopóki prądu nie zabraknie), ale to akurat bez znaczenia. Bardziej liczy się pomysłowość rozwiązania.

Kod wygąda tak:

10 PRINT CHR$(205.5+RND(1)); : GOTO 10

Efekt działania można obejrzeć na przykład tutaj:

Jak ten kod działa?

Bardzo prosto: w linii numer 10 (jedynej zresztą) najpierw generujemy losowo zero lub jedynkę, następnie dodajemy tę wygenerowaną liczbę do 205.5, w efekcie otrzymujemy 205.5 lub 206.5, wreszcie operator CHR$ obcina część ułamkową (a więc dostajemy 205 lub 206), po czym komenda PRINT wyświetla znak o tym kodzie (w Commodore znaki o kodzie 205 oraz 206 to są ukośniki - w jeden poprzek i w drugi). Na końcu przenosimy się na początek, czyli apiat' od nowa - i tak w kółko, do usranej.

Tym samym cały labirynt jest tak naprawdę zbudowany z dwóch znaków: / oraz \, powtarzanych bez końca w losowej kolejności. Do tego dochodzi oczywiście fakt, że fonty na Commodore 64 były kwadratowe oraz o stałej szerokości, w przeciwnym bowiem razie dostalibyśmy na wyjściu kompletny bałagan.

No dobra. Ale Commodore 64 to okolice późnego atarozoiku, tuż przed amigocenem. Pamiętają te czasy tylko najstarsi dinozaurowie (dinozaurzy?). Dziś nikt już nie będzie wyciągał ze strychu Commodore, bo można prościej.

Na przykład - w Pythonie.

Najkrótszy działający kod w Pythonie, który udało mi się znaleźć, a który robi dokładnie to samo, co powyższy kod w Commodore Basic, wygląda o tak:

C:\> python -c "while 1: print(__import__('random').choice('\/'), end='')"

Efekt?

Raczej słaby.

Dlaczego?

Domyślny font windowsowej konsoli NIE jest kwadratowy. Trzeba wejść w ustawienia terminala i w zakładce "font" wybrać "Raster fonts", a rozmiar ustawić na "8x8" (to jedyna dostępna opcja, w której długość = szerokość).

Uruchamiamy kod raz jeszcze...

(można kliknąć w obrazek poniżej, otworzy się w pełnej wielkości)

Jak to działa?

Odrobinę inaczej, niż w Basic-u. To jednak Python.

Na początku mamy wywołanie interpretera python z opcją -c (czyli przekazujemy kod do wykonania w wierszu poleceń, nie w pliku).

Potem, w cudzysłowie, mamy kod właściwy, czyli:

while 1:

otwiera nieskończoną pętlę (jedynka zostaje niejawnie skonwertowana na wartość FalseTrue, ponieważ nie jest zerem, pętla będzie ganiać w nieskończoność, tzn. tak naprawdę dopóki ktoś łaskawie nie wciśnie Ctrl-C)

print(__import__('random').choice('\/'), end='')

Ta komenda składa sie z kilku elementów. Całkiem w środku mamy ciąg dwóch znaków (ukośniki jeden i drugi), który trafia na wejście funkcji choice (zaimportowanej w locie z biblioteki random), która przekształca ten dwuznakowy tekst w dwulementową tablicę, a następnie losuje z niej jeden element. Wreszcie wynik funkcji choice(), czyli jeden z ukośników, trafia na wejście funkcji print(), która jako drugi argument (nazwany "end") przyjmuje znak, który ma być wyświetlony na końcu tekstu. Trzeba tak zrobić, ponieważ domyślnie każdy tekst jest zakończony znakiem końca linii, a tego nie chcemy.

Jak widać trochę to bardziej skomplikowane od wersji z Commodore, ale w dalszym ciągu zmieściliśmy się w jednej linii kodu (i to wraz z wywołaniem interpretera!), no i efekt ten sam.

Ciekawe?

Nie bardzo?

No to macie tu kotka:

https://xpil.eu/k7c

9 komentarzy

  1. A ja całe życie byłem uczony, że 0==false, a 1 == true… Ale ja 4 lata młodszy jestem od Ciebie, może przez ten czas się zmieniło…

  2. Tu mi się dowcip przypomniał specjalistyczny.
    Jak zająć programistę? Dać mu zadanie:
    – Przeczytaj zdanie poniżej.
    – Przeczytaj zdanie powyżej.

  3. Ciekawe dlaczego w oryginalnym kodzie jest owe 205.5? Przecież jakby dać 205 i dodawać zero albo jedynkę też byśmy uzyskali 205 albo 206 i nie trzeba by było części ułamkowej obcinać.

    1. No to powiedz jak w Commodore wylosować zero albo jedynkę tak, żeby się to dało wrzucić w tę jedną linię kodu.

  4. W PHP:

    while (1) echo ['/','\\'][rand(0,1)];
    

    EDIT: widzę, że pierwszy apostrof Twój skrypt do komentarzy przenosi na dół, hmmm…

Leave a Comment

Komentarze mile widziane.

Jeżeli chcesz do komentarza wstawić kod, użyj składni:
[code]
tutaj wstaw swój kod
[/code]

Jeżeli zrobisz literówkę lub zmienisz zdanie, możesz edytować komentarz po jego zatwierdzeniu.