Code-golf: generate pascal's triangle

2019-01-16 14:17发布

Generate a list of lists (or print, I don't mind) a Pascal's Triangle of size N with the least lines of code possible!

Here goes my attempt (118 characters in python 2.6 using a trick):

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

Explanation:

  • the first element of the list comprehension (when the length is 0) is [1]
  • the next elements are obtained the following way:
  • take the previous list and make two lists, one padded with a 0 at the beginning and the other at the end.
    • e.g. for the 2nd step, we take [1] and make [0,1] and [1,0]
  • sum the two new lists element by element
    • e.g. we make a new list [(0,1),(1,0)] and map with sum.
  • repeat n times and that's all.

usage (with pretty printing, actually out of the code-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)))

output:

             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

23条回答
做自己的国王
2楼-- · 2019-01-16 14:37

The following is just a Scala function returning a List[List[Int]]. No pretty printing or anything. Any suggested improvements? (I know it's inefficient, but that's not the main challenge now, is it?). 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(_))}

Or perhaps:

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(_))
}

(I'm a Scala noob, so please be nice to me :D )

查看更多
We Are One
3楼-- · 2019-01-16 14:37

a Perl version (139 chars 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";
}

output starts from 1 2 1

查看更多
Emotional °昔
4楼-- · 2019-01-16 14:43

PHP, 115 chars

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

If you don't care whether print_r() displays the output array in the correct order, you can shave it to 113 chars like

$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];}
查看更多
淡お忘
5楼-- · 2019-01-16 14:44

My attempt in C++ (378c). Not anywhere near as good as the rest of the posts.. but I'm proud of myself for coming up with a solution on my own =)

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";
  }
}
查看更多
Explosion°爆炸
6楼-- · 2019-01-16 14:46

VBA, 122 chars:

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
查看更多
时光不老,我们不散
7楼-- · 2019-01-16 14:47

K (Wikipedia), 15 characters:

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

Example output:

  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)

It's also easily explained:

p:{x {+':x,0} \ 1}
   ^ ^------^ ^ ^
   A    B     C D
  • p is a function taking an implicit parameter x.

  • p unfolds (C) an anonymous function (B) x times (A) starting at 1 (D).

  • The anonymous function simply takes a list x, appends 0 and returns a result by adding (+) each adjacent pair (':) of values: so e.g. starting with (1 2 1), it'll produce (1 2 1 0), add pairs (1 1+2 2+1 1+0), giving (1 3 3 1).


Update: Adapted to K4, which shaves off another two characters. For reference, here's the original K3 version:

p:{x{+':0,x,0}\1}
查看更多
登录 后发表回答