我拿起了这本书的副本10 打印 CHR$(205.5+RND(1)); : 转到 10
- http://www.amazon.com/10-PRINT-CHR-205-5-RND/dp/0262018462
本书讨论了Commodore 64 BASIC单行产生的艺术:
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
这只是重复将 PETSCII 集中的随机字符 205 或 206 打印到屏幕上:
- http://en.wikipedia.org/wiki/PETSCII
- https://vimeo.com/26472518
我不确定为什么原版使用字符 205 和 206 而不是相同的 109 和 110。另外,我更喜欢在开头添加清晰的内容。这是我通常在 C64 中输入的内容:
1?CHR$(147)
2?CHR$(109.5+RND(1));:GOTO2
RUN
您可以在模拟器中亲自尝试所有这些操作,例如使用Flash或JavaScript的模拟器:
- http://codeazur.com.br/stuff/fc64_final/
http://www.kingsquare.nl/jsc64
将上述代码输入列出的模拟器时,您需要意识到
- ( 是 *
- ) 为 (
- + 是 ]
我决定写一个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
下划线分别为 shift+H、shift+N 和 shift+O。我不能在这里粘贴字符,因为它们是特定于PETSCII的。此外,C64输出看起来更漂亮;)
您可以在此处阅读有关 C64 BASIC 缩写的信息:
- http://www.commodore.ca/manuals/c64_programmers_reference/c64-programmers_reference_guide-02-basic_language_vocabulary.pdf
这个怎么样?
# The characters you want to use
chars=( $'xe2x95xb1' $'xe2x95xb2' )
# 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=($'xe2x95xb1' $'xe2x95xb2'); n=${#c[@]}; clear; while :; do printf -- "${c[RANDOM%n]}"; done
如果您事先知道要打印多少个字符,则可以摆脱循环(此处为80 * 24 = 1920)
c=($'xe2x95xb1' $'xe2x95xb2'); 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
看了一些UTF的东西之后:
2571 BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
2572 BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
(╱ and ╲) seem best.
f="╱╲";while :;do print -n ${f[(RANDOM % 2) + 1]};done
也可以在 zsh 工作(感谢 OFTC 上的克林特给了我一些东西)
这是我刚刚发布到@climagic的 39 个字符的命令行解决方案:
grep -ao "[/\]" /dev/urandom|tr -d \n
在 bash 中,您可以删除 [/\] match 表达式两边的双引号,使其比 C64 解决方案更短,但我已包含它们以获得良好的度量和交叉外壳兼容性。如果 grep 有一个 1 个字符的选项来制作 grep 修剪换行符,那么你可以制作这个 27 个字符。
我知道这不使用 Unicode 字符,所以也许它不算数。可以在/dev/urandom 中对 Unicode 字符进行 grep,但这需要很长时间,因为该序列出现的频率较低,如果您通过管道传输它,命令管道可能会"坚持"相当长一段时间,然后由于行缓冲而产生任何内容。
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
很抱歉发布,但这里有 38 个字符的 bash 版本。
yes 'printf \u$[2571+RANDOM%2]'|bash
使用for
而不是yes
将其膨胀到 40 个字符:
for((;;)){ printf \u$[2571+RANDOM%2];}
109 chr for Python 3 这是我能得到的最小的。
#!/usr/bin/python3
import random
while True:
if random.randrange(2)==1:print('u2572',end='')
else:print('u2571',end='')
#!/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()
下面是适合 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)"