Подтвердить что ты не робот

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:

4b9b3361

Ответ 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()