23

我拿起一本书10 PRINT CHR$(205.5+RND(1)); : 转到 10

本书讨论了 Commodore 64 BASIC 单行所产生的艺术:

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

这只是从 PETSCII 集合中重复地将字符 205 或 206 随机打印到屏幕上:

我不确定为什么原版使用字符 205 和 206 而不是相同的 109 和 110。另外,我更喜欢在开头添加一个 clear。这是我通常在 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;

两个问题:

  1. 有什么建议可以让这个更简洁吗?
  2. 对更好的输出字符有什么建议吗?正斜杠和反斜杠几乎没有那么漂亮,因为它们的点不对齐。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

下划线分别为 shift+H、shift+N 和 shift+O。我无法在此处粘贴字符,因为它们是 PETSCII 特有的。此外,C64 输出看起来更漂亮;)

您可以在此处阅读有关 C64 BASIC 缩写的信息:

4

8 回答 8

6

在看了一些 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 的 Clint 给了我一些信息)

于 2012-11-28T18:31:43.493 回答
6

这个怎么样?

# 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
于 2012-11-28T18:51:25.073 回答
4

这是我刚刚发布到@climagic的 39 个字符的命令行解决方案:

grep -ao "[/\\]" /dev/urandom|tr -d \\n

在 bash 中,您可以删除 [/\] 匹配表达式周围的双引号,使其比 C64 解决方案更短,但我将它们包括在内是为了获得良好的度量和跨 shell 兼容性。如果 grep 有 1 个字符的选项来使 grep 修剪换行符,那么您可以使这 27 个字符。

我知道这不使用 Unicode 字符,所以可能不算数。可以在 /dev/urandom 中对 Unicode 字符进行 grep,但这将花费很长时间,因为该序列出现的频率较低,并且如果您通过管道传输它,命令管道可能会“粘住”很长一段时间,然后再产生任何到期的东西行缓冲。

于 2013-05-02T14:03:42.817 回答
3

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

更新:

还有一些。

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
于 2013-05-02T14:07:49.337 回答
2

抱歉,发布了 38 个字符的 bash 版本。

yes 'printf \\u$[2571+RANDOM%2]'|bash

使用for而不是将其yes膨胀到 40 个字符:

for((;;)){ printf \\u$[2571+RANDOM%2];}
于 2015-03-03T22:31:09.943 回答
2

Python 3 为 109 chr,这是我能得到的最小的。

#!/usr/bin/python3
import random
while True:
    if random.randrange(2)==1:print('\u2572',end='') 
    else:print('\u2571',end='')
于 2020-03-13T18:38:37.660 回答
1
#!/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()
于 2018-01-19T09:13:41.990 回答
1

这是适合 127 个字符的 Batch 版本:

cmd /v:on /c "for /l %a in (0,0,0) do @set /a "a=!random!%2" >nul & if "!a!"=="0" (set /p ".=/" <nul) else (set /p ".=\" <nul)"
于 2020-08-09T21:07:51.003 回答