代码高尔夫:生成帕斯卡的三angular形

生成一个列表(或打印,我不介意)一个大小为N的Pascal三angular形 ,代码行数最less!

这里是我的尝试( 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)] 

说明:

  • 列表理解的第一个元素(当长度为0时)是[1]
  • 接下来的元素是通过以下方式获得的:
  • 采取以前的名单,并作出两个名单,一个填充0开头和另一端。
    • 例如,对于第二步,我们取[1]并使[0,1][1,0]
  • 按元素对两个新列表进行求和
    • 例如,我们创build一个新的列表[(0,1),(1,0)]并与总和进行映射。
  • 重复n次,就这些了。

用法(用漂亮的打印,实际上不用代码 – 高尔夫xD):

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

输出:

  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 

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

 p=:!/~@i. 

这使用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 

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

 p:{x{+':x,0}\1} 

示例输出:

  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) 

这也很容易解释:

 p:{x {+':x,0} \ 1} ^ ^------^ ^ ^ ABCD 
  • p是一个取隐含参数x

  • (C)从1 (D)开始,展开一个匿名函数(B) x次(A)。

  • 匿名函数只需要一个列表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} 

哈斯格尔 ,58个字符:

 r 0=[1] r(n+1)=zipWith(+)(0:rn)$r n++[0] pn=map r[0..n] 

输出:

 *Main> p 5 [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1],[1,5,10,10,5,1]] 

更可读:

 -- # 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] 

C中的69C:

 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;} 

像这样使用它:

 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; } 

F# :81个字符

 let f=bigint.Factorial let px=[for n in 0I..x->[for k in 0I..n->fn/fk/f(nk)]] 

说明:我懒得像Haskell和K程序员一样聪明,所以我采取了直线前进的路线:Pascal三angular形中的每个元素可以使用第n行和第k行唯一标识,其中每个元素的值是n!/(k! (nk)!

Python:75个字符

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

较短的序言版本(112而不是164):

 n([X],[X]). n([H,I|T],[A|B]):-n([I|T],B),A is H+I. p(0,[[1]]):-!. p(N,[R,S|T]):-O is N-1,p(O,[S|T]),n([0|S],R). 

另一个刺(python):

 def pascals_triangle(n): x=[[1]] for i in range(n-1): x.append(list(map(sum,zip([0]+x[-1],x[-1]+[0])))) return x 

Haskell,164C格式化:

 il=zipWith(+)(0:l)$l++[0] fp=map (concatMap$(' ':).show)f$iterate i[1] cnl=if(length l<n)then cn$' ':l++" "else l cl l=map(c(length$last l))l pt n=cl$take n fp 

没有格式化,52C:

 il=zipWith(+)(0:l)$l++[0] pt n=take n$iterate i[1] 

它更可读的forms:

 iterateStep row = zipWith (+) (0:row) (row++[0]) pascalsTriangle n = take n $ iterate iterateStep [1] -- For the formatted version, we reduce the number of rows at the final step: formatRow r = concatMap (\l -> ' ':(show l)) r formattedLines = map formatRow $ iterate iterateStep [1] centerTo width line = if length line < width then centerTo width (" " ++ line ++ " ") else line centerLines lines = map (centerTo (length $ last lines)) lines pascalsTriangle n = centerLines $ take n formattedLines 

和perl,111C,没有集中:

 $n=<>;$p=' 1 ';for(1..$n){print"$p\n";$x=" ";while($p=~s/^(?= ?\d)(\d* ?)(\d* ?)/$2/){$x.=($1+$2)." ";}$p=$x;} 

Scheme – 100个字符的压缩版本

  ()()()定义(lh)(if(> ih)'()(cons r(l(1+ i)(map +(cons 0 r)(append r'(0))))) (11'(1))) 

这是一个更可读的forms(269个字符):

 (定义(帕斯卡高度)
   (定义(下一行)
     (地图+
          (缺0行)
          (附加行'(0))))

   (定义(iter i行)
     (如果(>我身高)
         “()
         (缺点
               (iter(1+ i)
                     (下一行)))))

   (iter 1'(1)))

VBA / VB6 (392字符w /格式)

 Public Function PascalsTriangle(ByVal pRows As Integer) Dim iRow As Integer Dim iCol As Integer Dim lValue As Long Dim sLine As String For iRow = 1 To pRows sLine = "" For iCol = 1 To iRow If iCol = 1 Then lValue = 1 Else lValue = lValue * (iRow - iCol + 1) / (iCol - 1) End If sLine = sLine & " " & lValue Next Debug.Print sLine Next End Function 

PHP 100个字符

 $v[]=1;while($a<34){echo join(" ",$v)."\n";$a++;for($k=0;$k<=$a;$k++)$t[$k]=$v[$k-1]+$v[$k];$v=$t;} 

Ruby,83c:

 def p(n);n>0?(m=p(n-1);k=m.last;m+[([0]+k).zip(k+[0]).map{|x|x[0]+x[1]}]):[[1]];end 

testing:

 irb(main):001:0> def p(n);n>0?(m=p(n-1);k=m.last;m+[([0]+k).zip(k+[0]).map{|x|x[0]+x[1]}]):[[1]];end => nil irb(main):002:0> p(5) => [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1]] irb(main):003:0> 

另一个python解决scheme,如果内置函数名字较短,可能会更短… 106个字符。

 from itertools import* r=range p=lambda n:[[len(list(combinations(r(i),j)))for j in r(i+1)]for i in r(n)] 

另一个尝试,在序言 (我正在练习xD),不要太短,只是164c:

 s([],[],[]). s([H|T],[J|U],[K|V]):-s(T,U,V),K is H+J. l([1],0). l(P,N):-M is N-1,l(A,M),append(A,[0],B),s(B,[0|A],P). p([],-1). p([H|T],N):-M is N-1,l(H,N),p(T,M). 

说明:

  • s =元素的和列表
  • l =三angular形的第N行
  • p =大小为N的整个三angular形

VBA,122个字符:

 Sub p(n) For r = 1 To n l = "1" v = 1 For c = 1 To r - 1 v = v / c * (r - c) l = l & " " & v Next Debug.Print l Next End Sub 

几年前我写了这个C ++版本:

 #include <iostream> int main(int,char**a){for(int b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0;b<atoi(a[1]);(d|f|h)>1?e*=d>1?--d:1,g*=f>1?--f:1,i*=h>1?--h:1:((std::cout<<(i*g?e/(i*g):1)<<" "?d=b+=c++==b?c=0,std::cout<<std::endl?1:0:0,h=d-(f=c):0),e=d,g=f,i=h));} 

以下只是一个返回List[List[Int]]的Scala函数。 没有漂亮的印刷或任何东西 任何build议的改进? (我知道效率不高,但这不是现在的主要挑战,是吗?)。 145 C.

 def p(n: Int)={def h(n:Int):List[Int]=n match{case 1=>1::Nil;case _=>(0::h(n-1) zipAll(h(n-1),0,0)).map{n=>n._1+n._2}};(1 to n).toList.map(h(_))} 

也许:

 def pascal(n: Int) = { def helper(n: Int): List[Int] = n match { case 1 => 1 :: List() case _ => (0 :: helper(n-1) zipAll (helper(n-1),0,0)).map{ n => n._1 + n._2 } } (1 to n).toList.map(helper(_)) } 

(我是斯卡拉noob,所以请对我很好:D)

一个Perl版本(139字符w / o shebang)

 @p = (1,1); while ($#p < 20) { @q =(); $z = 0; push @p, 0; foreach (@p) { push @q, $_+$z; $z = $_ } @p = @q; print "@p\n"; } 

输出从1 2 1开始

PHP,115个字符

 $t[][]=1; for($i=1;$i<$n;++$i){ $t[$i][0]=1; for($j=1;$j<$i;++$j)$t[$i][$j]=$t[$i-1][$j-1]+$t[$i-1][$j]; $t[$i][$i]=1;} 

如果你不关心print_r()是否按照正确的顺序显示输出数组,你可以把它刮到113个字符

 $t[][]=1; for($i=1;$i<$n;++$i){ $t[$i][0]=$t[$i][$i]=1; for($j=1;$j<$i;++$j)$t[$i][$j]=$t[$i-1][$j-1]+$t[$i-1][$j];} 

Perl,63个字符:

 for(0..9){push@z,1;say"@z";@z=(1,map{$z[$_-1]+$z[$_]}(1..$#z))} 

我在C ++中的尝试(378c)。 没有任何地方和其他post一样好,但是我为自己提出解决scheme感到自豪=)

 int* pt(int n) { int s=n*(n+1)/2; int* t=new int[s]; for(int i=0;i<n;++i) for(int j=0;j<=i;++j) t[i*n+j] = (!j || j==i) ? 1 : t[(i-1)*n+(j-1)] + t[(i-1)*n+j]; return t; } int main() { int n,*t; std::cin>>n; t=pt(n); for(int i=0;i<n;++i) { for(int j=0;j<=i;j++) std::cout<<t[i*n+j]<<' '; std::cout<<"\n"; } } 

旧线程,但我今天在另一个论坛上写了这个答复:

 def pascals_triangle(n): x=[[1]] for i in range(n-1): x.append([sum(i) for i in zip([0]+x[-1],x[-1]+[0])]) return x for x in pascals_triangle(5): print('{0:^16}'.format(x)) [1] [1, 1] [1, 2, 1] [1, 3, 3, 1] [1, 4, 6, 4, 1]