Bash Версия C64 Code Art: 10 PRINT CHR $(205.5 + RND (1));: GOTO 10
Я взял копию книги 10 PRINT CHR $(205.5 + RND (1));: GOTO 10
В этой книге обсуждается искусство, созданное одной линией Commodore 64 BASIC:
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
Это несколько раз печатает случайный символ 205 или 206 на экране из набора PETSCII:
Я не уверен, почему оригинал использует символы 205 и 206 вместо идентичных 109 и 110. Кроме того, я предпочитаю добавлять четкость в начале. Это то, что я обычно набираю в C64:
1?CHR$(147)
2?CHR$(109.5+RND(1));:GOTO2
RUN
Вы можете попробовать все это для себя в эмуляторе, например, с помощью Flash или JavaScript:
Я решил, что было бы забавно написать строку bash, чтобы сделать что-то подобное.
В настоящее время у меня есть:
clear; while :; do [ $(($RANDOM%2)) -eq 0 ] && (printf "\\") || (printf "/"); done;
Два вопроса:
- Любые предложения для более кратким образом?
- Любые предложения
для лучшего выходного символа? Передняя и обратная коса
не так красиво, поскольку их очки не выстраиваются в линию. Символы, используемые из PETSCII, являются специальными символами, а не слэшами. Я не видел ничего в ASCII, который мог бы работать, но, может быть, вы можете предложить способ привлечь персонажа из UTF-8 или еще что-то?
Лучший ОТВЕТ ДАЛЕЕ
Самый короткий для bash (40 символов):
yes 'c=(╱ ╲);printf ${c[RANDOM%2]}'|bash
Вот короткий для zsh (53 символа):
c=(╱ ╲);clear;while :;do printf ${c[RANDOM%2+1]};done
Вот псевдоним, который мне нравится вставлять в мой .bashrc или .profile
alias art='c=(╱ ╲);while :;do printf "%s" ${c[RANDOM%2]};done'
Смешно сравнивать это с самым коротким, что я могу сделать для C64 BASIC (23 символа):
1?C_(109.5+R_(1));:G_1
Подчерки - сдвиг + H, сдвиг + N и сдвиг + O соответственно. Я не могу вставить символ здесь, поскольку они специфичны для PETSCII. Кроме того, вывод C64 выглядит более симпатичным;)
Здесь вы можете прочитать о аббревиатурах C64 BASIC:
Ответы
Ответ 1
Как насчет этого?
# The characters you want to use
chars=( $'\xe2\x95\xb1' $'\xe2\x95\xb2' )
# Precompute the size of the array chars
nchars=${#chars[@]}
# clear screen
clear
# The loop that prints it:
while :; do
printf -- "${chars[RANDOM%nchars]}"
done
Как однострочный с более короткими именами переменных, чтобы сделать его более кратким:
c=($'\xe2\x95\xb1' $'\xe2\x95\xb2'); n=${#c[@]}; clear; while :; do printf -- "${c[RANDOM%n]}"; done
Вы можете избавиться от цикла, если заранее знаете, сколько символов нужно печатать (здесь 80 * 24 = 1920)
c=($'\xe2\x95\xb1' $'\xe2\x95\xb2'); n=${#c[@]}; clear; printf "%s" "${c[RANDOM%n]"{1..1920}"}"
Или, если вы хотите включить символы непосредственно вместо своего кода:
c=(╱ ╲); n=${#c[@]}; clear; while :; do printf "${c[RANDOM%n]}"; done
Наконец, с размером массива c
предварительно вычисленным и удалением ненужных пробелов и кавычек (и я не могу получить меньше этого):
c=(╱ ╲);clear;while :;do printf ${c[RANDOM%2]};done
Число байтов, используемых для этой строки:
$ wc -c <<< 'c=(╱ ╲);clear;while :;do printf ${c[RANDOM%2]};done'
59
Изменить. Забавный способ с помощью команды yes
:
clear;yes 'c=(╱ ╲);printf ${c[RANDOM%2]}'|bash
Он использует 50 байтов:
$ wc -c <<< "clear;yes 'c=(╱ ╲);printf \${c[RANDOM%2]}'|bash"
51
или 46 символов:
$ wc -m <<< "clear;yes 'c=(╱ ╲);printf \${c[RANDOM%2]}'|bash"
47
Ответ 2
После просмотра некоторых материалов UTF:
2571 BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
2572 BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
(╱ и ╲) кажутся лучшими.
f="╱╲";while :;do print -n ${f[(RANDOM % 2) + 1]};done
также работает в zsh (спасибо Клинту на OFTC за то, что он дал мне бит)
Ответ 3
Вот мое решение для командной строки на 39 символов, которое я только что разместил в @climagic:
grep -ao "[/\\]" /dev/urandom|tr -d \\n
В bash вы можете удалить двойные кавычки вокруг выражения соответствия [/\] и сделать его еще короче, чем решение C64, но я включил их для хорошей оценки и совместимости с оболочкой. Если в grep есть параметр 1 символа, чтобы сделать grep trim newlines, вы можете сделать это 27 символов.
Я знаю, что это не использует символы Unicode, поэтому, возможно, это не считается. Можно использовать grep для символов Unicode в /dev/urandom, но это займет много времени, потому что эта последовательность возникает реже, и если вы ее подключаете, конвейер команд, вероятно, "прилипает" довольно долго, для буферизации строк.
Ответ 4
Bash теперь поддерживает Unicode, поэтому нам не нужно использовать последовательности символов UTF-8, такие как $'\ xe2\x95\xb1'.
Это моя самая правильная версия: она зацикливается, печатает либо/или\на основе случайного числа, как другие.
for((;;x=RANDOM%2+2571)){ printf "\U$x";}
41
Мой предыдущий лучший был:
while :;do printf "\U257"$((RANDOM%2+1));done
45
И этот "чит" с использованием встроенного Unicode (я думаю, для очевидности, ремонтопригодности и простоты, это мой любимый).
Z=╱╲;for((;;)){ printf ${Z:RANDOM&1:1};}
40
Мой предыдущий лучший был:
while Z=╱╲;do printf ${Z:RANDOM&1:1};done
41
И вот еще несколько.
while :;do ((RANDOM&1))&&printf "\U2571"||printf "\U2572";done
while printf -v X "\\\U%d" $((2571+RANDOM%2));do printf $X;done
while :;do printf -v X "\\\U%d" $((2571+RANDOM%2));printf $X;done
while printf -v X '\\U%d' $((2571+RANDOM%2));do printf $X;done
c=('\U2571' '\U2572');while :;do printf ${c[RANDOM&1]};done
X="\U257";while :;do printf $X$((RANDOM%2+1));done
Теперь это выполняется до тех пор, пока мы не получим переполнение стека (не другое!), так как bash пока еще не поддерживает устранение хвостового вызова.
f(){ printf "\U257"$((RANDOM%2+1));f;};f
40
И это моя попытка реализовать грубую форму устранения хвостового процесса. Но когда у вас достаточно и нажмите ctrl-c, ваш терминал исчезнет.
f(){ printf "\U257"$((RANDOM%2+1));exec bash -c f;};export -f f;f
UPDATE:
И еще несколько.
X=(╱ ╲);echo -e "\b${X[RANDOM&1]"{1..1000}"}" 46
X=("\U2571" "\U2572");echo -e "\b${X[RANDOM&1]"{1..1000}"}" 60
X=(╱ ╲);while :;do echo -n ${X[RANDOM&1]};done 46
Z=╱╲;while :;do echo -n ${Z:RANDOM&1:1};done 44
Ответ 5
Извините за некропостинг, но здесь bash версия в 38 символов.
yes 'printf \\u$[2571+RANDOM%2]'|bash
используя for
вместо yes
, раздувает это до 40 символов:
for((;;)){ printf \\u$[2571+RANDOM%2];}
Ответ 6
#!/usr/bin/python3
import random
import sys
while True:
if random.randrange(2)==1:sys.stdout.write("\u2571")
else:sys.stdout.write("\u2572")
sys.stdout.flush()