代码高尔夫:谢尔宾斯基三角形

37

挑战

输出N次迭代的Sierpinski三角形的ASCII表示形式的最短代码,该三角形由以下ASCII三角形制成:

 /\
/__\

输入为一个正整数。

测试用例

Input:
    2
Output:
       /\
      /__\
     /\  /\
    /__\/__\

Input:
    3
Output:
           /\
          /__\
         /\  /\
        /__\/__\
       /\      /\
      /__\    /__\
     /\  /\  /\  /\
    /__\/__\/__\/__\

Input:
    5
Output:
                                   /\
                                  /__\
                                 /\  /\
                                /__\/__\
                               /\      /\
                              /__\    /__\
                             /\  /\  /\  /\
                            /__\/__\/__\/__\
                           /\              /\
                          /__\            /__\
                         /\  /\          /\  /\
                        /__\/__\        /__\/__\
                       /\      /\      /\      /\
                      /__\    /__\    /__\    /__\
                     /\  /\  /\  /\  /\  /\  /\  /\
                    /__\/__\/__\/__\/__\/__\/__\/__\
                   /\                              /\
                  /__\                            /__\
                 /\  /\                          /\  /\
                /__\/__\                        /__\/__\
               /\      /\                      /\      /\
              /__\    /__\                    /__\    /__\
             /\  /\  /\  /\                  /\  /\  /\  /\
            /__\/__\/__\/__\                /__\/__\/__\/__\
           /\              /\              /\              /\
          /__\            /__\            /__\            /__\
         /\  /\          /\  /\          /\  /\          /\  /\
        /__\/__\        /__\/__\        /__\/__\        /__\/__\
       /\      /\      /\      /\      /\      /\      /\      /\
      /__\    /__\    /__\    /__\    /__\    /__\    /__\    /__\
     /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\
    /__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\/__\

代码行数包括输入/输出(即完整程序)。


9
我开始没有更多的想法了……你一直在大力挖掘“控制台输出数据”这一点。也许现在是放弃这个点子的时候了。《Lasers》不同寻常的地方之一就是输入并不平凡。或者干脆整个放松一下,但我已经习惯了周四的打球时间。即使我没有提交很多解决方案,我仍会对你的大部分问题进行摸索。 - dmckee --- ex-moderator kitten
11
LiraNuna,你做得非常棒。你的挑战获得最多的投票是有原因的。即使你再也不发表任何内容,你仍将成为Stack Overflow的传奇人物。感谢你带来的乐趣! - DigitalRoss
2
@dmckee:那我会尝试更多地思考激光的方式。虽然设计激光很困难,但我有一些想法,只是还没有完善。我可以始终开始“反向”系列!(反向蜂巢!) - LiraNuna
ephemient: *"文本格式化"*?方块或沙漏式呢?它们是使用输入变量从ASCII创建的。那些不好吗?我个人喜欢方块和蜂巢 - 它们足够简单,适合新手创建长答案并参与,但是具有适当代码可以缩短答案的潜力。 - LiraNuna
@LiraLuna:这些都很有趣,我感到很遗憾自己来晚了,没能做出什么好的贡献。尽管我“不喜欢”,但还是回答了(可能因为只用几分钟就写出了J语言的解决方案,而不是通常需要几个小时)。 - ephemient
显示剩余9条评论
21个回答

4

C语言

这个算法和Perl答案相同,但需要更多的字符,共131个。

a,b;main(c,v)char**v;{c=1<<atoi(v[1]);for(a=0;a<c;a++,puts(""))
for(b=c;b--;write(1,b&~a?"    ":a&1?"/__\\":" /\\ ",4-2*(b>a)))--b;}

我曾认为write(1,...)是UNIX API,但在Windows上编译和运行也没有问题。

如果你将char替换为int,虽然可以节省一个字符,但这可能存在法律问题。


2
write() 是Unix API和POSIX的一部分,但Windows提供了许多POSIX函数。它们全部都是“不赞成使用”的,因此在Windows上“正确”的方法是使用_write(),但a)这是代码高尔夫比赛,b)POSIX不再被支持的想法让我哈哈大笑。 - Chris Lutz

4

MATLAB - 64个字符(脚本版本)

这假设您的工作区已经定义了变量N

A=[' /\ ';'/__\'];for i=1:N-1,B=32*ones(2^i);A=[B A B;A A];end;A

MATLAB - 78个字符(m文件函数版本)

N作为参数传递给函数s

function A=s(N),A=[' /\ ';'/__\'];for i=1:N-1,B=32*ones(2^i);A=[B A B;A A];end

4

标识(不完全符合要求):47个字符

to F:n if:n[repeat 3[F(:n-1)fd 2^:n rt 120]]end

我只在http://www.calormen.com/Logo/上进行了测试,因此不知道它是否可移植。虽然它不符合要求,但是在这里使用logo肯定是合适的语言吧? :) 我喜欢在写作时,logo仅比golfscript和J短一个字符。


2

Lua, 139 characters

t={" /\\ ","/__\\"}for i=2,(...)do for j=1,#t do
t[#t+1]=t[j]:rep(2)k=(" "):rep(#t[j]/2)t[j]=k..t[j]..k end end
print(table.concat(t,"\n"))

2

Nroff, 542

$ nroff -rn=5 file.n

.pl 1
.nf
.de b
. nr i 0
. while d\\$1\\ni \{\
.   \\$3 \\$1\\ni \\$2\\ni
.   nr i +1
. \}
..
.de push
. nr i 0
. while d\\$2\\ni \{\
.   nr i +1
. \}
. nr j 0
. while d\\$1\\nj \{\
.   ds \\$2\\ni \&\\*[\\$1\\nj]
.   nr i +1
.   nr j +1
. \}
..
.ds l0 \& /\[rs] \&
.ds l1 "/__\[rs]
.ds s \&\ 
.de o
. ds \\$2 \&\\*s\\*[\\$1]\\*s
..
.de p
. ds \\$2 \&\\*[\\$1]\\*[\\$1]
..
.de assign
. ds \\$2 \&\\*[\\$1]
..
.nr a 2
.while \na<=\nn \{\
. ds s \&\*s\*s
. b l m o
. b l n p
. b m l assign
. push n l
. nr a +1
.\}
.de t
\\*[\\$1]
..
.b l zz t

1

Clojure: 174个字符

算法从其他人那里偷来的。

(doseq[q((fn f[n](if(= n 1)[" /\\ ""/__\\"](let[z(f(dec n))](concat(map #(let[y(repeat(Math/pow 2(dec n))\ )](apply str(concat y % y)))z)(map str z z)))))(read))](println q))

其中38个字符是括号。 :(

(doseq [q ((fn f [n]
           (if (= n 1)
             [" /\\ " "/__\\"]
             (let [z (f (dec n))]
               (concat
                (map #(let [y (repeat (Math/pow 2 (dec n))\ )]
                        (apply str (concat y % y))) z)
                (map str z z))))) (read))] 
  (println q))

1

Python,120个字符(递归解决方案)

S=lambda n:n<2and[" /\ ","/__\\"]or[" "*n+x+" "*n for x in S(n/2)]+[x+x for x in S(n/2)]
print"\n".join(S(1<<input()-1))

我开始接替 @fserb 的工作...


1

F#,225个字符

let rec p n=if n=1 then" "else p(n-1)+p(n-1)
and S n=if n=1 then[" /\\ ";"/__\\"]else let s=S(n-1)in List.append(List.map(fun s->p(n)+s+p(n))s)(List.map(fun x->x+x)s)
for s in S(int(System.Console.ReadLine()))do printfn"%s"s

4
一定有办法缩短这个可怕的 System.Console.ReadLine... 多浪费字节啊 ;) - Thomas Levesque

1

GolfScript(45 44个字符)

~(' /\ /__\ '4/)@{.+\.{[2$.]*}%\{.+}%+\}*;n*

类似于gnibbler的解决方案。我的初始尝试已经非常相似,然后我看了他的并借鉴了一些想法。


0

Python,186个字符(UNIX行终止符)

for j in range(1,n):
 for s in p:
  print s
 x=2**j;y=2*x;p.extend(['']*x)
 for i in range(y-1,-1,-1):
  if i<x:
   s=' '*x;p[i]=s+p[i]+s
  else:
   q=p[i-x];p[i]=q+q

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接