Sierpinsky三角形是通过截取三角形,将高度和宽度减小1/2,创建3个所得三角形副本并将每个三角形与其他两个三角形接触的方式创建的分形。如下图所示,对生成的三角形反复进行此过程,以生成Sierpinski三角形。
编写程序以生成Sierpinski三角形。您可以通过绘制实际三角形或使用随机算法生成图片来使用想要生成图案的任何方法。您可以绘制像素,ascii艺术作品或任何您想要的东西,只要输出看起来与上面显示的最后一张图片相似即可。最少的角色获胜。
Sierpinsky三角形是通过截取三角形,将高度和宽度减小1/2,创建3个所得三角形副本并将每个三角形与其他两个三角形接触的方式创建的分形。如下图所示,对生成的三角形反复进行此过程,以生成Sierpinski三角形。
编写程序以生成Sierpinski三角形。您可以通过绘制实际三角形或使用随机算法生成图片来使用想要生成图案的任何方法。您可以绘制像素,ascii艺术作品或任何您想要的东西,只要输出看起来与上面显示的最后一张图片相似即可。最少的角色获胜。
Answers:
插入空格以提高可读性,不计入。
<title></title><canvas></canvas><script>
for(x=k=128;x--;)for(y=k;y--;)
x&y||document.body.firstChild.getContext("2d").fillRect(x-~y/2,k-y,1,1)
</script>
它的核心是应用为像素着色的规则,x & y == 0
通过条件x&y||
为生成一个“ Sierpinski直角三角形”。并且x-~y/2,k-y
是坐标转换以产生近似等边的显示。
较不正确(HTML格式)的版本是126个字符:
<canvas><script>
for(x=k=128;x--;)for(y=k;y--;)
x&y||document.body.firstChild.getContext("2d").fillRect(x-~y/2,k-y,1,1)
</script>
(这种不太正确的方式是,它省略了title
元素和元素的结束标记,canvas
尽管省略了它们并不会更改文档的解释,但对于正确的文档而言,这两者都是必需的。)
通过消除k
常量64
,可以节省三个字符,但结果较小。我不会考虑该8
选项,因为它的细节不足。
请注意,大于等于256的尺寸要求上具有属性,<canvas>
以从默认值增加画布的尺寸。
<canvas id=c>
然后c.getContext
。缩短循环:for(x=k=128;x--;)for(y=k;y--;)
x&y?0:
可以用x&y||
其他不错的解决方案代替。
' /\ /__\ '4/){.+\.{[2$.]*}%\{.+}%+\}3*;n*
输出:
/\
/__\
/\ /\
/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\ /__\/__\
/\ /\ /\ /\
/__\ /__\ /__\ /__\
/\ /\ /\ /\ /\ /\ /\ /\
/__\/__\/__\/__\/__\/__\/__\/__\
对于较大的三角形,将“ 3”更改为更大的数字。
最大程度的打高尔夫球,小巧的形象:
#!/usr/bin/env python3
from cairo import*
s=SVGSurface('_',97,84)
g=Context(s)
g.scale(97,84)
def f(w,x,y):
v=w/2
if w>.1:f(v,x,y);f(v,x+w/4,y-v);f(v,x+v,y)
else:g.move_to(x,y);g.line_to(x+v,y-w);g.line_to(x+w,y);g.fill()
f(1,0,1)
s.write_to_png('s.png')
需要python3-cairo
。
要获得一个不错的大图像,我需要239个字符。
import cairo as c
谁能为您节省几个字符
Mathematica-32个字符
Nest[Subsuperscript[#,#,#]&,0,5]
Mathematica-37个字符
Grid@CellularAutomaton[90,{{1},0},31]
这将产生一个0和1的2D表,其中1表示Sierpinski Triangle。
ArrayPlot@CellularAutomaton[90, {{1}, 0}, 31]
或可以更好地显示第二个解决方案MatrixPlot@CellularAutomaton[90, {{1}, 0}, 31]
。
ReliefPlot@
...
使用规则90自动机。
x=' '*31
x+='.'+x
exec"print x;x=''.join(' .'[x[i-1]!=x[i-62]]for i in range(63));"*32
这更长,但是更漂亮。
x=' '*31
x+=u'Δ'+x
exec u"print x;x=''.join(u' Δ'[x[i-1]!=x[i-62]]for i in range(63));"*32
编辑:直接玩弦,摆脱了令人讨厌的长时间切片,使输出更漂亮。
输出:
Δ
Δ Δ
Δ Δ
Δ Δ Δ Δ
Δ Δ
Δ Δ Δ Δ
Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ
Δ Δ Δ Δ
Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ
Δ Δ Δ Δ
Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ
Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ
,/.(,~,.~)^:6,'o'
这并不理想,因为三角形偏斜且后面有很多空格-但我还是觉得很有趣。
输出:
o
oo
o o
oooo
o o
oo oo
o o o o
oooooooo
o o
oo oo
o o o o
oooo oooo
o o o o
oo oo oo oo
o o o o o o o o
oooooooooooooooo
o o
oo oo
o o o o
oooo oooo
o o o o
oo oo oo oo
o o o o o o o o
oooooooo oooooooo
o o o o
oo oo oo oo
o o o o o o o o
oooo oooo oooo oooo
o o o o o o o o
oo oo oo oo oo oo oo oo
o o o o o o o o o o o o o o o o
oooooooooooooooooooooooooooooooo
o o
oo oo
o o o o
oooo oooo
o o o o
oo oo oo oo
o o o o o o o o
oooooooo oooooooo
o o o o
oo oo oo oo
o o o o o o o o
oooo oooo oooo oooo
o o o o o o o o
oo oo oo oo oo oo oo oo
o o o o o o o o o o o o o o o o
oooooooooooooooo oooooooooooooooo
o o o o
oo oo oo oo
o o o o o o o o
oooo oooo oooo oooo
o o o o o o o o
oo oo oo oo oo oo oo oo
o o o o o o o o o o o o o o o o
oooooooo oooooooo oooooooo oooooooo
o o o o o o o o
oo oo oo oo oo oo oo oo
o o o o o o o o o o o o o o o o
oooo oooo oooo oooo oooo oooo oooo oooo
o o o o o o o o o o o o o o o o
oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo oo
o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
快速说明:
动词(,~,.~)
是这里所做的工作。这是一个钩子,它首先,.
将参数缝合到自身(o
-> oo
),然后将原始参数附加到输出:
oo
变成
oo
o
该动词重复6次^:6
,每次迭代的输出成为下一次迭代的输入。所以
oo
o
变成
oooo
o o
oo
o
依次变成
oooooooo
o o o o
oo oo
o o
oooo
o o
oo
o
等。然后,我在追加上使用了倾斜副词,,/.
以对角线读取行以拉直(ish)三角形。正如randomra所指出的,我不需要这样做。我本来可以倒转|.
很多,以获得相同的结果。更好的是,我本可以用来(,,.~)^:6,'o'
完全保存相反的步骤。
嗯,你生活和学习。:-)
|.(,~,.~)^:6,'o'
较短,没有多余的空间。而且(,~,.~)^:6,1
还可以仅12个字符提供不错的输入!
A←67⍴0⋄A[34]←1⋄' ○'[1+32 67⍴{~⊃⍵:⍵,∇(1⌽⍵)≠¯1⌽⍵⋄⍬}A]
说明:
A←67⍴0
:A是67个零的向量A[34]←1
:第34个元素是1{...}A
:以A开头,请执行以下操作:~⊃⍵:
:如果当前行的第一个元素为零⍵,∇
:将当前行添加到答案中,然后递归:(1⌽⍵)≠¯1⌽⍵
:向量,其中每个元素是上一代中其相邻元素的XOR⋄⍬
:否则,我们就完成了32 67⍴
:将其格式化为67x32矩阵1+
:添加一个以从字符数组中选择正确的值' ○'[
... ]
:输出一个空格(不是三角形的一部分)或一个圆(当它是三角形的一部分时)输出:
○ ○○ ○○ ○○○○ ○○ ○○○○ ○○○○ ○○○○○○○○○ ○○ ○○○○ ○○○○ ○○○○○○○○○ ○○○○ ○○○○○○○○○ ○○○○○○○○○ ○○○○○○○○○○○○○○○○○○ ○○ ○○○○ ○○○○ ○○○○○○○○○ ○○○○ ○○○○○○○○○ ○○○○○○○○○ ○○○○○○○○○○○○○○○○○○ ○○○○ ○○○○○○○○○ ○○○○○○○○○ ○○○○○○○○○○○○○○○○○○ ○○○○○○○○○ ○○○○○○○○○○○○○○○○○○ ○○○○○○○○○○○○○○○○○○ ○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○○
我不太擅长打Haskell代码。
solve n = tri (putStrLn "") [2^n] n
tri m xs 1 =
do putStrLn (l1 1 xs "/\\" 0)
putStrLn (l1 1 xs "/__\\" 1)
m
tri m xs n=tri m' xs (n-1)
where m'=tri m (concat[[x-o,x+o]|x<-xs]) (n-1)
o=2^(n-1)
l1 o [] s t=""
l1 o (x:xs) s t=replicate (x-o-t) ' '++s++l1 (x+2+t) xs s t
输出solve 4
为:
/\
/__\
/\ /\
/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\ /__\/__\
/\ /\ /\ /\
/__\ /__\ /__\ /__\
/\ /\ /\ /\ /\ /\ /\ /\
/__\/__\/__\/__\/__\/__\/__\/__\
QBasic 151个字符
例如,这是如何在QBasic中完成。
SCREEN 9
H=.5
P=300
FOR I=1 TO 9^6
N=RND
IF N > 2/3 THEN
X=H+X*H:Y=Y*H
ELSEIF N > 1/3 THEN
X=H^2+X*H:Y=H+Y*H
ELSE
X=X*H:Y=Y*H
END IF
PSET(P-X*P,P-Y*P)
NEXT
我本来想在postbybys解决方案(实际上使用规则18 :)上发布一些建议,但是我没有足够的声誉来发表评论,所以我提出了另一个答案。自从他改变了方法以来,我补充了一些解释。我的建议是:
这将导致以下代码(93个字符):
x=[0]*63
x[31]=1
exec"print'%d'*63%tuple(x);x=[a^b for a,b in zip(x[1:]+[0],[0]+x[:-1])];"*32
但是我进一步优化了,首先通过使用longint而不是整数数组并仅打印二进制表示形式(75个字符):
x=2**31
exec"print'%d'*63%tuple(1&x>>i for i in range(63));x=x<<1^x>>1;"*32
最后,通过打印八进制表示形式,它已经由printf插值支持(42个字符):
x=8**31
exec"print'%063o'%x;x=x*8^x/8;"*32
所有这些都将打印:
000000000000000000000000000000010000000000000000000000000000000
000000000000000000000000000000101000000000000000000000000000000
000000000000000000000000000001000100000000000000000000000000000
000000000000000000000000000010101010000000000000000000000000000
000000000000000000000000000100000001000000000000000000000000000
000000000000000000000000001010000010100000000000000000000000000
000000000000000000000000010001000100010000000000000000000000000
000000000000000000000000101010101010101000000000000000000000000
000000000000000000000001000000000000000100000000000000000000000
000000000000000000000010100000000000001010000000000000000000000
000000000000000000000100010000000000010001000000000000000000000
000000000000000000001010101000000000101010100000000000000000000
000000000000000000010000000100000001000000010000000000000000000
000000000000000000101000001010000010100000101000000000000000000
000000000000000001000100010001000100010001000100000000000000000
000000000000000010101010101010101010101010101010000000000000000
000000000000000100000000000000000000000000000001000000000000000
000000000000001010000000000000000000000000000010100000000000000
000000000000010001000000000000000000000000000100010000000000000
000000000000101010100000000000000000000000001010101000000000000
000000000001000000010000000000000000000000010000000100000000000
000000000010100000101000000000000000000000101000001010000000000
000000000100010001000100000000000000000001000100010001000000000
000000001010101010101010000000000000000010101010101010100000000
000000010000000000000001000000000000000100000000000000010000000
000000101000000000000010100000000000001010000000000000101000000
000001000100000000000100010000000000010001000000000001000100000
000010101010000000001010101000000000101010100000000010101010000
000100000001000000010000000100000001000000010000000100000001000
001010000010100000101000001010000010100000101000001010000010100
010001000100010001000100010001000100010001000100010001000100010
101010101010101010101010101010101010101010101010101010101010101
当然,还有一个图形解决方案(131个字符):
from PIL.Image import*
from struct import*
a=''
x=2**31
exec"a+=pack('>Q',x);x=x*2^x/2;"*32
fromstring('1',(64,32),a).save('s.png')
:D
x=8**31;exec"print'%o'%x;x^=x/8;"*32
注意:这不是我的代码,因此不应作为答案。我在研究另一个CG问题以模拟8086 CPU时发现了这一点。附带的文本文件感谢David Stafford,但这是我能想到的最好的东西。
我发布此消息是因为它很聪明,简短,而且我认为您希望看到它。
它利用重叠的操作码在较小的空间中打包更多的指令。令人惊讶的聪明。这是机器代码:
B0 13 CD 10 B3 03 BE A0 A0 8E DE B9 8B 0C 32 28 88 AC C2 FE 4E 75 F5 CD 16 87 C3 CD 10 C3
直接解码看起来像这样:
0100: B0 13 mov AL, 13h
0102: CD 10 int 10h
0104: B3 03 mov BL, 3h
0106: BE A0 A0 mov SI, A0A0h
0109: 8E DE mov DS, SI
010B: B9 8B 0C mov CX, C8Bh
010E: 32 28 xor CH, [BX+SI]
0110: 88 AC C2 FE mov [SI+FEC2h], CH
0114: 4E dec SI
0115: 75 F5 jne/jnz -11
运行时,发生在0x0115处的跳转时,请注意它会跳回到0x010C,就在上一条指令的中间:
0100: B0 13 mov AL, 13h
0102: CD 10 int 10h
0104: B3 03 mov BL, 3h
0106: BE A0 A0 mov SI, A0A0h
0109: 8E DE mov DS, SI
010B: B9 8B 0C mov CX, C8Bh
010E: 32 28 xor CH, [BX+SI]
0110: 88 AC C2 FE mov [SI+FEC2h], CH
0114: 4E dec SI
0115: 75 F5 jne/jnz -11
010C: 8B 0C mov CX, [SI]
010E: 32 28 xor CH, [BX+SI]
0110: 88 AC C2 FE mov [SI+FEC2h], CH
0114: 4E dec SI
0115: 75 F5 jne/jnz -11
010C: 8B 0C mov CX, [SI]
辉煌!希望你们不要介意我分享这个。我知道这本身并不是答案,但是挑战很有趣。
它在起作用:
这是使用HTML答案的技巧,^ i & j
使它打印漂亮的输出将再花费1个字符(您可以通过牺牲来获得非常难看的输出a^
)。
a=32,j;main(i){for(;++i<a;)putchar(a^i&j);++j<a&&main(puts(""));}
为了让它非常转(32^i&j)
,以(32|!(i&j))
从打开++i<a
到++i<=a
。然而,在外表上浪费木炭对我来说似乎是无用的东西。
丑陋的输出:
! ! ! ! ! ! ! ! ! ! ! ! ! ! !
"" "" "" "" "" "" "" ""
"# !"# !"# !"# !"# !"# !"# !"#
$$$$ $$$$ $$$$ $$$$
!$%$% ! !$%$% ! !$%$% ! !$%$%
""$$&& ""$$&& ""$$&& ""$$&&
"#$%&' !"#$%&' !"#$%&' !"#$%&'
(((((((( ((((((((
! ! !()()()() ! ! ! !()()()()
"" ""((**((** "" ""((**((**
"# !"#()*+()*+ !"# !"#()*+()*+
$$$$((((,,,, $$$$((((,,,,
!$%$%()(),-,- ! !$%$%()(),-,-
""$$&&((**,,.. ""$$&&((**,,..
"#$%&'()*+,-./ !"#$%&'()*+,-./
0000000000000000
! ! ! ! ! ! !0101010101010101
"" "" "" ""0022002200220022
"# !"# !"# !"#0123012301230123
$$$$ $$$$0000444400004444
!$%$% ! !$%$%0101454501014545
""$$&& ""$$&&0022446600224466
"#$%&' !"#$%&'0123456701234567
((((((((0000000088888888
! ! !()()()()0101010189898989
"" ""((**((**0022002288::88::
"# !"#()*+()*+0123012389:;89:;
$$$$((((,,,,000044448888<<<<
!$%$%()(),-,-010145458989<=<=
""$$&&((**,,..0022446688::<<>>
"#$%&'()*+,-./0123456789:;<=>?
我实际上有点喜欢它的外观。但是,如果您坚持要漂亮,可以停靠四个字符。漂亮的输出:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
!! !! !! !! !! !! !! !
! ! ! ! ! ! ! !
!! !!!! !!!! !!!! !
! ! ! ! ! ! ! !
!! !! !! !
! ! ! !
!!!!!! !!!!!!!! !
! ! ! ! ! ! ! !
!! !! !! !
! ! ! !
!! !!!! !
! ! ! !
!! !
! !
!!!!!!!!!!!!!! !
! ! ! ! ! ! ! !
!! !! !! !
! ! ! !
!! !!!! !
! ! ! !
!! !
! !
!!!!!! !
! ! ! !
!! !
! !
!! !
! !
!
!
放弃了较旧的108字符蜂窝自动机版本。
j,d[99][99];main(i){d[0][31]=3;for(;i<64;)d[j+1][i]=putchar(32|d[j][i+2]^d[j][i++]);++j<32&&main(puts(""));}
所以我认为我不会比这更短,所以我将解释代码。由于一些技巧可能会有用,因此我将不再赘述。
j,d[99][99]; // these init as 0
main(i){ //starts at 1 (argc)
d[0][48]=3; //seed the automata (3 gives us # instead of !)
for(;i<98;) // print a row
d[j+1][i]=putchar(32|d[j][i+2]]^d[j][i++]);
//relies on undefined behavoir. Works on ubuntu with gcc ix864
//does the automata rule. 32 + (bitwise or can serve as + if you know
//that (a|b)==(a^b)), putchar returns the char it prints
++j<32&&main(puts(""));
// repeat 32 times
// puts("") prints a newline and returns 1, which is nice
}
一些输出
# #
# #
# # # #
# #
# # # #
# # # #
# # # # # # # #
# #
# # # #
# # # #
# # # # # # # #
# # # #
# # # # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # #
# #
# # # #
# # # #
# # # # # # # #
# # # #
# # # # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # #
# # # #
# # # # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # #
# # # # # # # #
# # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
作为专门针对MsDos简介的sizecoder,我设法提出了一个仅占用10个字节的程序。
十六进制:
04 13 CD 10 20 E9 B4 0C E2 F6
在asm中:
X: add al,0x13
int 0x10
and cl,ch
mov ah,0x0C
loop X
我编写的第一个版本是“ Colpinski”,它的大小为16字节,甚至可以交互,您可以使用键盘和鼠标更改颜色。与另一个大小编码器“ Frag”一起,我们将其减少到13个字节,从而允许一个仅包含核心例程的10字节程序。
当动画化事物时,它会变得更加有趣,所以我要提到另一个版本,Zoompinski 64-试图模仿512字节中“ Zoompinski C64”的确切行为-同样对于MsDos,顾名思义,它的大小为64字节。
可以进一步优化到31字节,同时又不失优雅,色彩和对称性(上述链接后面的源代码和可执行文件可用)
-7 -4 moveto
14 0 rlineto
7{true upath dup
2{120 rotate uappend}repeat[2 0 0 2 7 4]concat}repeat
matrix setmatrix
stroke
Ghostscript输出:
这是通过将已绘制的内容递归三倍来绘制图形的。
第一步是画一条线。将该行保存为用户路径,然后在每次旋转120度后再添加两次用户路径。[2 0 0 2 7 4]concat
将“旋转点”移动到下一个白色“中心三角形”的中心,该三角形将被我们已有的三角形的复制包围。在这里,我们返回到步骤1(创建向上旋转三倍的向上运动)。
迭代次数由第3行中的第一个数字控制。
最难看的是,您真的需要斜视才能看到输出;)
2|!/~i.32
产生输出
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1
0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
当然,您可以以图形方式显示它:
load 'viewmat'
viewmat 2|!/~i.32
({((-1⌷⍴⍵)⌽⍵,∊⍵)⍪⍵,⍵}⍣⎕)1 2⍴'/\'
说明
1 2⍴'/\'
:创建一个1×2字符矩阵 /\
{((-1⌷⍴⍵)⌽⍵,∊⍵)⍪⍵,⍵}
:一个函数,在右边的自变量两侧都用空格填充,以创建两倍宽的矩阵,然后将右边自变量本身加倍的底部叠加到底部。/\
将成为/ \ / \ / \
⍣⎕
:重复执行功能(用户输入)次数。输出示例
/\
/\/\
/\ /\
/\/\/\/\
/\ /\
/\/\ /\/\
/\ /\ /\ /\
/\/\/\/\/\/\/\/\
/\ /\
/\/\ /\/\
/\ /\ /\ /\
/\/\/\/\ /\/\/\/\
/\ /\ /\ /\
/\/\ /\/\ /\/\ /\/\
/\ /\ /\ /\ /\ /\ /\ /\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
({(⍵,∊⍵)⍪⍵,⍵}⍣⎕)1 1⍴'○'
讲解
1 1⍴'○'
:创建一个1×1字符矩阵 ○
{(⍵,∊⍵)⍪⍵,⍵}
:一个函数,该函数用空格填充右边的右参数以创建两倍宽的矩阵,然后将右边的参数本身加倍到底部。○
将成为○ ○○
⍣⎕
:重复执行功能(用户输入)次数。输出示例
○
○○
○ ○
○○○○
○ ○
○○ ○○
○ ○ ○ ○
○○○○○○○○
○ ○
○○ ○○
○ ○ ○ ○
○○○○ ○○○○
○ ○ ○ ○
○○ ○○ ○○ ○○
○ ○ ○ ○ ○ ○ ○ ○
○○○○○○○○○○○○○○○○
我参加聚会晚了两年,但令我惊讶的是,还没有人采取这种方法
from pylab import*
x=[[1,1],[1,0]]
for i in'123':x=kron(x,x)
imsave('a',x)
使用Kronecker产品将矩阵替换为其自身的多个副本。
我可以通过x=kron(x,x);x=kron(x,x)
在第三行中使用以获得三个可见级别的16x16像素图像来保存两个字符,或者将另一个字符添加到迭代器中,最后得到2 ^ 16 x 2 ^ 16 = 4.3 Gigapixel图像和15个三角形级别。
徽标,75个字符
仅第一个函数使用59个字符,第二个函数使用迭代的大小和深度/次数调用第一个。因此,您可以使用以下命令从解释器中调用第一个函数:e 99 5或要输出的任何大小
to e :s :l
if :l>0[repeat 3[e :s/2 :l-1 fd :s rt 120]]
end
to f
e 99 5
end
to f
和end
周围e 99 5
,你有更少的字符完全执行的程序。另外,在UCBLogo中(尽管不是其他版本),您可以在变量上丢失冒号以保存更多字符。
' *'{~(,,.~)^:9 ,1
*
**
* *
****
* *
** **
* * * *
********
* *
** **
* * * *
**** ****
* * * *
** ** ** **
* * * * * * * *
****************
* *
** **
* * * *
**** ****
* * * *
** ** ** **
* * * * * * * *
******** ********
* * * *
** ** ** **
* * * * * * * *
**** **** **** ****
* * * * * * * *
** ** ** ** ** ** ** **
* * * * * * * * * * * * * * * *
********************************
from turtle import*
def l():left(60)
def r():right(60)
def f():forward(1)
def L(n):
if n:n-=1;R(n);l();L(n);l();R(n)
else:f()
def R(n):
if n:n-=1;L(n);r();R(n);r();L(n)
else:f()
l();L(8)
绘制分形线填充Sierpinsky三角形
ht();speed(0);up();goto(20-window_width()/2, 20-window_height()/2);down()
在导入后插入。这将使其运行得更快,并确保输出适合画布。
Image@Array[BitAnd,{2,2}^9,0]
可以用类似的方式绘制Sierpinski四面体:
Image3D[1-Array[BitXor,{2,2,2}^7,0]]
-2字节归功于FrownyFrog
(,.~,~' '&,.^:#)@[&0' /\',:'/__\'"_
这是彼得·泰勒(Peter Taylor)的ascii艺术版本,已转换为J。可以使用不太漂亮的版本保存字节,但是为什么呢?
/\
/__\
/\ /\
/__\/__\
/\ /\
/__\ /__\
/\ /\ /\ /\
/__\/__\/__\/__\
@]^:[
-> @[&0
和' /\ '
->' /\'
&0
技巧?
,~
周围。
后记, 205 203
[48(0-1+0+1-0)49(11)43(+)45(-)/s{dup
0 eq{exch{[48{1 0 rlineto}49 1 index
43{240 rotate}45{120 rotate}>>exch
get exec}forall}{exch{load
exch 1 sub s}forall}ifelse 1 add}>>begin
9 9 moveto(0-1-1)9 s fill
使用字符串进行重写,递归最终的次数完全相同。但是克服了宏方法的深度限制。
编辑: fill
比短stroke
。
缩进和评论。
%!
[ % begin dictionary
48(0-1+0+1-0) % 0
49(11) % 1
43(+) % +
45(-) % -
/s{ % string recursion-level
dup 0 eq{ % level=0
exch{ % iterate through string
[
48{1 0 rlineto} % 0
49 1 index % 1
43{240 rotate} % +
45{120 rotate} % -
>>exch get exec % interpret turtle command
}forall
}{ % level>0
exch{ % iterate through string
load exch % lookup charcode
1 sub s % recurse with level-1
}forall
}ifelse
1 add % return recursion-level+1
}
>>begin
9 9 moveto(0-1-1)9 s fill % execute and fill
添加后0 setlinewidth
,可以更好地了解这一点。
我将添加它,主要是因为我在该站点上渐近线看到或多或少没有答案。一些字节浪费了很好的格式和通用性,但是我可以接受。更改A,B和C会更改包含三角形的角的位置,但可能不会改变您的思维方式。增加不等式中的数字以增加深度。
pair A=(0,0),B=(1,0),C=(.5,1);void f(pair p,int d){if(++d<7){p*=2;f(p+A*2,d);f(p+B*2,d);f(p+C*2,d);}else{fill(shift(p/2)*(A--B--C--cycle));}}f((0,0),0);
或松散且可读
pair A=(0,0), B=(1,0), C=(.5,1);
void f(pair p, int d) {
if (++d<7) {
p *= 2;
f(p+A*2,d);
f(p+B*2,d);
f(p+C*2,d);
} else {
fill(shift(p/2)*(A--B--C--cycle));
}
}
f((0,0),0);
因此,渐近线是一种精巧的矢量图形语言,具有类似于C的语法。对于有些技术图表非常有用。默认情况下,输出当然是矢量格式(eps,pdf,svg),但基本上可以转换为imagemagick支持的所有内容。输出:
(由于使用了Laikoni,所以需要-12个字节,(使用zip和list理解而不是zipWith和lambda,这是生成第一行的更好方法)
i#n|let k!p=p:(k+1)![m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))|(l,m,r)<-zip3(1:p)p$tail p++[1]];x=1<$[2..2^n]=mapM(putStrLn.map("M "!!))$take(2^n)$1!(x++0:x)
说明:
该函数在迭代步骤后i#n
绘制高度的ASCII三角形。2^n
i
内部使用的编码将空位置编码为1
,将完整位置编码为0
。因此,三角形的第一行被编码为[1,1,1..0..1,1,1]
与2^n-1
零两侧的一。为了构建此列表,我们从列表开始x=1<$[2..2^n]
,即[2..2^n]
所有映射到的列表1
。然后,我们将完整列表构建为x++0:x
k!p
给定行索引k
和相应的运算符(以下详细说明),该运算符将p
生成一个无限的跟随其后的行列表p
。我们使用1
和上述起始线调用它以获取整个三角形,然后仅取第一2^n
行。然后,我们简单地打印各行,替换1
用的空间和0
与M
(通过访问列表"M "
在位置0
或1
)。
运算符k!p
定义如下:
k!p=p:(k+1)![m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))|(l,m,r)<-zip3(1:p)p$tail p++[1]]
首先,我们生成的三个版本p
:1:p
这是p
一个1
前缀,p
本身tail p++[1]
这就是一切,但第一个元素p
,用1
追加。然后,我们对这三个列表进行压缩,从而有效地将其所有元素p
与它们的左邻居和右邻居相邻,如(l,m,r)
。我们使用列表推导来计算新行中的相应值:
m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))
要理解此表达式,我们需要意识到有两种基本情况需要考虑:要么简单地扩展前一行,要么就在三角形中的空白点开始的位置。在第一种情况下,如果附近的任何地点都被填补,我们将得到一个填补的地点。这可以计算为m*l*r
:如果这三个值中的任何一个为零,则新值为零。另一种情况比较棘手。在这里,我们基本上需要边缘检测。下表列出了八个可能的邻域,并在新行中显示了结果值:
000 001 010 011 100 101 110 111
1 1 1 0 1 1 0 1
产生该表的简单公式1-m*r*(1-l)-m*l*(1-r)
就是m*(2*l*r-l-r)+1
。现在我们需要在这两种情况之间进行选择,这是我们使用行号的地方k
。如果为mod k (2^(n-i)) == 0
,则必须使用第二种情况,否则,使用第一种情况。0^(mod k(2^n-i))
因此,该术语是指0
是否必须使用第一种情况,以及1
是否必须使用第二种情况。结果,我们可以使用
m*l*r+(m*(l*r-l-r)+1)*0^mod k(2^(n-i))
总计-如果我们使用第一种情况,则简单地得到m*l*r
,而在第二种情况下,将添加一个附加项,得出的总和m*(2*l*r-l-r)+1
。