V , 54 , 50 bajtów
¬ ~9ñ9É 11|á
ñ2ñ20lá
ñ$18é 9ñ^y|Ehé
Pf xxywk$hP>ñd
Wypróbuj online!
W przeciwieństwie do zwykłego programu ten nie zawiera znaków, które nie mogą być drukowane.
Wyjaśnienie:
¬ ~ " Insert the entire printable ASCII range
9ñ ñ " 9 times:
9É " Insert 9 spaces at the beginning of this line
11| " Move to the 11'th column on this line
á<CR> " And append a newline after the 11'th column
Teraz bufor wygląda następująco:
!
"#
$%
&'
()
*+
,-
./
01
23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
Teraz budujemy środek:
2ñ ñ " Two times:
20l " Move 20 characters to the right (because 'l' == 'right', duh)
á<CR> " Append a newline
Tutaj robi się trochę dziwnie.
$ " Move to the end of this line
18é " Insert 18 spaces before the last character
9ñ " Repeat the following 9 times:
^ " Move to the first non-whitespace character
y| " Yank all the whitespace before the current character.
" We'll call this the "Leading whitespace register"
E " Move to the end of the current WORD (up to before a space)
h " Move back one character
é<CR> " And insert a newline before the current character
P " Paste the leading whitespace for indentation
f " Move forward to a space
xx " Delete two characters
" (Note how we are inbetween the two bottom branches right now)
yw " Yank everything upto the next branch (all spaces)
" We'll paste this on the line up so that we can yank it again later
" To keep track of how far apart the branches are
k$ " Move up a line and to the end of that line
hP " Move back a character and paste the whitespace we yanked
> " Indent this line by one space
ñ " End the loop
Oto ważna uwaga. >Komenda jest rzeczywiście operatora , co oznacza, że nie robi nic bez argumentu, tekst działać dalej. Na przykład,
>_ "Indent the current line
>> "Indent the current line
>j "Indent the current and next line
>G "Indent every line
Ale ponieważ to polecenie jest w pętli, możemy zapisać znak, nie dając operatora. Na końcu pętli, jeśli jakiś operator oczekuje, wypełnia _(bieżący wiersz) jako argument niejawnie.
Przyznaję, że ta pętla jest trochę dziwna i trudno jest śledzić, jak powinien wyglądać cały tekst w danym momencie. Możesz więc użyć tego prostszego programu, aby zobaczyć, jak będzie wyglądał po N pętlach.
Jeśli ustawisz na 9, zobaczysz, że mamy trochę dodatkowego tekstu do pozbycia się. (Tylko bieżąca linia).
Więc usuwamy bieżącą linię za pomocą dd. Ale poczekaj! Wiesz, jak powiedziałem, że operatorzy muszą wziąć argument, który jest czasem domyślnie wypełniony? Argumenty są również domyślnie wypełniane na końcu programu. Więc zamiast ddlub d_(które są równoważne), możemy po prostu di pozwolić V wypełnić _dla nas.