10 PRINT
2022-01-15
Dyskusja na temat „czym jest sztuka, czym jest piękno” jest z nami tak długo jak długo istnieje klasa intelektualno-próżniacza, która mogła zadawać sobie takie pytania i szukać na nie odpowiedzi. Będąc bękartem tej klasy, odziedziczyłem tylko pół genotypu, jestem próżniakiem, dlatego na potrzeby dzisiejszego dnia zdefiniuję sztukę i piękno jako „to, co da się wyrazić jedną linijką w najgorszym1 BASIC-u”.
Najsłynniejszym przykładem „generowanej sztuki” jest 10 PRINT
, jedna linijka w BASIC-u na C64, która generuje pseudolosowy labirynty. Jest możliwa tylko dzięki szczęśliwym zbiegom okoliczności. Prześledźmy ją krok po kroku.
10 PRINT CHR$(205.5 + RND(0)); : GOTO 10
PRINT
nie trzeba nikomu tłumaczyć. Natomiast warto rozważyć dwa znaki interpunkcyjne. :
pozwala na separacje poleceń, ;
jest modyfikatorem dla PRINT
i powoduje, że następne znaki nie będą wypisywane w nowej linii. CHR$()
przyjmuje indeks i wypisuje znak znajdujący się pod nim w tabeli ASCII C642. Wartość 205 odpowiada /
. RND()
zwraca pseudolosową wartość w zakresie 0…1. GOTO
zamyka pętle.
CHR$()
jako parametr przyjmuje liczbę całkowitą. Jeśli podać mu liczbę zmiennoprzecinkową bezceremonialnie odrzuca wszystko po kropce bez zaokrąglania. To dla nas dobry zbieg okoliczności. Teraz rozważmy operację dodawania: 205.5 + [0…1]
daje nam liczby z zbioru 205.5…206.5
. Jak już ustaliliśmy CHR$()
jest kompletnie nieczułe i widzi tylko dwie wartości. 205, które w tablicy ASCII odpowiada /
i 206, kolejny szczęśliwy zbieg okoliczności, odpowiada \
.
Ostatni pozytywny zbieg okoliczności? Piksele na 8-bitowych maszynach to materiał premium, twórcy komputera nie mieli luksusu martwienia się jak typografia „oddycha” na ekranie. Odstępy pomiędzy liniami nie są tego warte.

I tyle: stawiamy znak \
lub /
i pozwalamy naszemu mózgowi poukładać ten szum w kształty. Magiczne sztuczki wydają się głupie, gdy je wyjaśnić.
Dla zabawy „przeportowałem” ten kod na odpowiednik w Pythonie, niestety, Linuksowy terminal jest już bogaty w piksele i nie da się tak łatwo uzyskać jednolitych linii. Po ustawieniu fontu z C64 efekt był już całkiem zadowalający.
from random import choice
while True: print(choice(['/', '\\']), end='')
Szybka opowiastka o: random.choice
zwraca losowy element z listy (tu dwuelementowa lista z \
i /
, oczywiście), end=''
do print()
powoduje to samo, co średnik w BASIC-u, operacja nie kończy się nową linią.

Miałem w tym tygodniu opublikować inny tekst, ale chyba jestem kolejną ofiarą zarazy™ i nie mogę myśleć zbyt jasno. Widziałem wczoraj wideo w którym Robin optymalizuje 10 PRINT w asemblerze i pomyślałem, że to temat łatwy i przyjemny, a może ktoś z subskrybentów nie wie o fenomenie.
Kilka lat temu MIT wypuściło książkę o 10 PRINT, ma ona 324 strony, co jest pewną formą meta-sztuki nieosiągalnej dla zwykłych śmiertelników. Skłamałbym gdybym powiedział, że ją przeczytałem. Dość uważnie przekartkowałem ją spacją.