コードゴルフ:パスカルの三角形を生成する
-
12-09-2019 - |
質問
リストのリストを生成します (または印刷しても構いません)。 パスカルの三角形 サイズ N で、コード行は最小限に抑えられます。
これが私の試みです(118文字) Python2.6 を使用して トリック):
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]
- 次の要素は次の方法で取得されます。
- 前のリストを使用して 2 つのリストを作成し、1 つは先頭に 0 を、もう 1 つは末尾に 0 を埋め込みます。
- 例えば2番目のステップとして、
[1]
そして、作ります[0,1]
そして[1,0]
- 例えば2番目のステップとして、
- 2 つの新しいリストを要素ごとに合計します。
- 例えば新しいリストを作ります
[(0,1),(1,0)]
そして合計でマップします。
- 例えば新しいリストを作ります
- n回繰り返すだけです。
使用法 (実際には 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)))
出力:
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
他のヒント
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}
^ ^------^ ^ ^
A B C D
p
暗黙的なパラメータを取る関数ですx
.p
無名関数 (B) を展開します (C)x
回 (A) から始まる1
(D)。無名関数は単にリストを受け取ります。
x
, 、追加0
(を追加して結果を返します)+
) 隣接する各ペア (':
) の値:だから、例えばで始まります(1 2 1)
, 、それは生成します(1 2 1 0)
, 、ペアを追加します(1 1+2 2+1 1+0)
, 、与える(1 3 3 1)
.
アップデート: さらに 2 文字を削る K4 に適応しました。参考までに、オリジナルの K3 バージョンを次に示します。
p:{x{+':0,x,0}\1}
ハスケル, 、58 文字:
r 0=[1]
r(n+1)=zipWith(+)(0:r n)$r n++[0]
p n=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 p x=[for n in 0I..x->[for k in 0I..n->f n/f k/f(n-k)]]
説明:私はHaskellのとKプログラマのように巧妙であるのが面倒だので、私はまっすぐの経路を取った:パスカルの三角形の各要素が一意の行nおよびCOL Kの値を用いて同定することができます各要素はn!/(k! (n-k)!
である。
パイソン: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).
別のスタブ(パイソン):
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
ハスケル、書式付き164Cます:
i l=zipWith(+)(0:l)$l++[0]
fp=map (concatMap$(' ':).show)f$iterate i[1]
c n l=if(length l<n)then c n$' ':l++" "else l
cl l=map(c(length$last l))l
pt n=cl$take n fp
の書式設定なしで、52Cます:
i l=zipWith(+)(0:l)$l++[0]
pt n=take n$iterate i[1]
それをより読みやすい形式ます:
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;}
スキーム - 100文字の圧縮バージョン
(define(P h)(define(l i r)(if(> i h)'()(cons r(l(1+ i)(map +(cons 0 r)(append r '(0))))))(l 1 '(1)))
このはそれをより読みやすい形式(269文字)であります:
(define (pascal height) (define (next-row row) (map + (cons 0 row) (append row '(0)))) (define (iter i row) (if (> i height) '() (cons row (iter (1+ i) (next-row row))))) (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;}
ルビー、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
テスト
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 のソリューション、
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 = 三角形の N 行目
- p = サイズ N の三角形全体
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の関数です。きれいな印刷も何もありませんありません。任意の提案の改善? (私はそれが非効率的であることを知っているが、それは今主要な課題ではありません、それはあります?)。 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(_))
}
(D私はそう私にいいことしてください、Scalaのnoobのです)
Perlバージョン(139文字W / Oシェバング)
@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)での私の試み。どこか近くとしてポストの残りの部分と良い..しかし、私は自分自身で解決策を考え出すために自分自身を誇りに思いません=)
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]