Code-golf:生成pascal的三角形

for*_*ran 37 algorithm code-golf combinatorics discrete-mathematics pascals-triangle

生成一个列表列表(或打印,我不介意)一个大小为N 的Pascal三角形,代码可能最少!

这是我的尝试(使用技巧python 2.6中的 118个字符):

c,z,k=locals,[0],'_[1]'
p=lambda n:[len(c()[k])and map(sum,zip(z+c()[k][-1],c()[k][-1]+z))or[1]for _ in range(n)]
Run Code Online (Sandbox Code Playgroud)

说明:

  • 列表理解的第一个元素(当长度为0时)是 [1]
  • 下一个元素是通过以下方式获得的:
  • 取前面的列表并制作两个列表,一个在开头填充0,在结尾填充另一个.
    • 例如,对于第二步,我们采取[1]并制造[0,1][1,0]
  • 按元素对两个新列表求和
    • 例如,我们制作一个新的列表[(0,1),(1,0)]并用sum来映射.
  • 重复n次,就是这样.

用法(漂亮的打印,实际上是代码-golf xD):

result = p(10)
lines = [" ".join(map(str, x)) for x in result]
for i in lines:
    print i.center(max(map(len, lines)))
Run Code Online (Sandbox Code Playgroud)

输出:

             1             
            1 1            
           1 2 1           
          1 3 3 1          
         1 4 6 4 1         
       1 5 10 10 5 1       
      1 6 15 20 15 6 1     
    1 7 21 35 35 21 7 1    
   1 8 28 56 70 56 28 8 1  
1 9 36 84 126 126 84 36 9 1
Run Code Online (Sandbox Code Playgroud)

ear*_*arl 17

K(维基百科),15个字符:

p:{x{+':x,0}\1}
Run Code Online (Sandbox Code Playgroud)

示例输出:

  p 10
(1
 1 1
 1 2 1
 1 3 3 1
 1 4 6 4 1
 1 5 10 10 5 1
 1 6 15 20 15 6 1
 1 7 21 35 35 21 7 1
 1 8 28 56 70 56 28 8 1
 1 9 36 84 126 126 84 36 9 1
 1 10 45 120 210 252 210 120 45 10 1)
Run Code Online (Sandbox Code Playgroud)

它也很容易解释:

p:{x {+':x,0} \ 1}
   ^ ^------^ ^ ^
   A    B     C D
Run Code Online (Sandbox Code Playgroud)
  • p是一个采用隐式参数的函数x.

  • p展开(C)匿名函数(B)x乘以(A)从1(D)开始.

  • 匿名函数只需要一个列表x,追加0并通过添加(+)每个相邻的对(':)值来返回结果:所以例如从开始(1 2 1),它将产生(1 2 1 0),添加对(1 1+2 2+1 1+0),给予(1 3 3 1).


更新:改编为K4,削减另外两个字符.作为参考,这是原始的K3版本:

p:{x{+':0,x,0}\1}
Run Code Online (Sandbox Code Playgroud)

  • 精彩!我怀疑是否会比这更短. (2认同)

ear*_*arl 15

J,APL家族的另一种语言,9个字符:

p=:!/~@i.
Run Code Online (Sandbox Code Playgroud)

这使用了J的内置"组合"动词.

输出:

   p 10
1 1 1 1 1  1  1  1  1   1
0 1 2 3 4  5  6  7  8   9
0 0 1 3 6 10 15 21 28  36
0 0 0 1 4 10 20 35 56  84
0 0 0 0 1  5 15 35 70 126
0 0 0 0 0  1  6 21 56 126
0 0 0 0 0  0  1  7 28  84
0 0 0 0 0  0  0  1  8  36
0 0 0 0 0  0  0  0  1   9
0 0 0 0 0  0  0  0  0   1
Run Code Online (Sandbox Code Playgroud)


sth*_*sth 14

Haskell,58个字符:

r 0=[1]
r(n+1)=zipWith(+)(0:r n)$r n++[0]
p n=map r[0..n]
Run Code Online (Sandbox Code Playgroud)

输出:

*Main> p 5
[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1],[1,5,10,10,5,1]]
Run Code Online (Sandbox Code Playgroud)

更具可读性:

-- # row 0 is just [1]
row 0     = [1]
-- # row (n+1) is calculated from the previous row
row (n+1) = zipWith (+) ([0] ++ row n) (row n ++ [0])
-- # use that for a list of the first n+1 rows
pascal n  = map row [0..n]
Run Code Online (Sandbox Code Playgroud)

  • 更短:`rn = take(n + 1)$ iterate(\ a-> zipWith(+)(0:a)$ a ++ [0])[1]` (8认同)

caf*_*caf 12

69C in C:

f(int*t){int*l=t+*t,*p=t,r=*t,j=0;for(*t=1;l<t+r*r;j=*p++)*l++=j+*p;}
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

int main()
{
#define N 10
    int i, j;
    int t[N*N] = {N};

    f(t);

    for (i = 0; i < N; i++)
    {
        for (j = 0; j <= i; j++)
            printf("%d ", t[i*N + j]);
        putchar('\n');
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Jul*_*iet 9

F#:81个字符

let f=bigint.Factorial
let p x=[for n in 0I..x->[for k in 0I..n->f n/f k/f(n-k)]]
Run Code Online (Sandbox Code Playgroud)

说明:我太懒了,不像Haskell和K程序员一样聪明,所以我采取了直接的路线:Pascal三角形中的每个元素都可以使用行n和col k唯一标识,其中每个元素的值是n!/(k! (n-k)!.


Tri*_*ych 7

Python:75个字符

def G(n):R=[[1]];exec"R+=[map(sum,zip(R[-1]+[0],[0]+R[-1]))];"*~-n;return R
Run Code Online (Sandbox Code Playgroud)