パスカルの菱形


20

パスカルの菱形(実際には三角形)は、次のパターンを追加することによって取得されます。

  *
 ***
  x

の代わりに

* *
 x

これは、各セルがそのすぐ上の行の3つのセルとその上の行2の1つのセルの合計であることを意味します。Pascalの三角形のように、0番目の行には1三角形を生成する単一の行があります。

これがパスカルの菱形の最初の数行です

      1
    1 1 1
  1 2 4 2 1
1 3 8 9 8 3 1

仕事

行番号(上から始まる)と列番号(その行の最初の非ゼロ項目から始まる)を指定すると、その特定のセルの値が出力されます。両方の入力に1または0のインデックスを付けることができます(必要に応じて組み合わせることができます)。

これはので、ソースコードのファイルサイズをできるだけ小さくすることを目指してください。

OEIS A059317



ソースコードのファイルサイズをできる限り小さくすることを目指してください。コマンドライン引数としてコードを配置するとどうなりますか。:P
エリックOutgolfer

ショートカットのグーグル検索を行ったところ、明らかにarxiv.org/abs/1504.04404は、結果を直接計算することはコードゴルフでは使用できないと述べています。
ジョリージョーカー

回答:


12

Haskell59 55バイト

パスカルの菱形?Haskellの菱形にもっと似ています!分かりましたか?

ØrjanJohansenのおかげで4バイト節約

私は自分の問題に取り組み、Haskellを練習すると思いました。これにより、より多くの人々がこれに答えることができることを願っています。

1!1=1
n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1]

オンラインでお試しください!

説明

これは最新のゴルフでは少し時代遅れです

計算する代わりに

  *
 ***
  x

計算する

*
***
  x

これは三角形全体を傾けて

1
1 1 1
1 2 4 2 1
1 3 8 9 8 3 1

これにより、すべての行が整列し、列のn番目のアイテムのインデックス付けが容易になります。次に、ベースケースを定義します。

0番目の行はすべてゼロです。

0!_=0

単一の1位置にある1,1ので、それを定義します

1!1=1

そして、最初の行の残りもゼロになるように定義します

1!_=0

次に、上記のパターンを使用して一般的なケースを再帰的に定義します。

n!k=(n-2)!(k-2)+(sum$map((n-1)!)[k-2..k])

それに私を打つ!これは私のものよりもずっときれいです。
ジュリアンウルフ

@JulianWolf申し訳ありませんが、私がこれを投稿したとき、Jorg以外の誰もこの問題をやっていないように見えました。私はまだあなたの解決策を見たいです。
小麦ウィザード

1
で4バイト節約できますn!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1]
Ørjanヨハンセン

10

パスカル、122バイト

まあ、それはパスカルのひし形です。

@manatworkのおかげで37バイト節約

function f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;

オンラインでお試しください!


if条件全体の括弧は意味がありません。(1日目ifは2文字を保存し、2回目ifthenキーワードとその前の数字の間にスペースを空けずに保存します。)ああ、変数rはまったく不要です。
マナトワーク

イデオンのパスカルという奇妙な動物。これまでにPascalバリアントで二重引用符で区切られた文字列を見たことはありません。あなたが削除することができますもう一つ:;functionend
マナトワーク

@manatworkええ、今あなたがそれについて言及したとき、他のすべてのオンライン編集者はそれについて不満を言いました
Uriel

@manatwork理解したかどうかわかりません。それだけでコードを長くすることは>= <=ないでしょうか?私はまだ保存する必要がありますif n=0
Uriel

@Urielさん、申し訳ありませんが、そのバージョンはもうありません。現在、私はfunction f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;
マナトワーク

7

PHP、86バイト

関数の行と列のみにインデックスを付けた再帰的な方法

function f($r,$c){return$r|$c?$r<0?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

オンラインでお試しください!

PHP、114バイト

再帰的な方法の完全なプログラム行と列0-Indexed

<?=f(...$_GET);function f($r,$c){return$r|$c?$r<0|$c<0|$c>2*$r?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

オンラインでお試しください!

PHP、129バイト

行および列0-Indexed

for(;$r<=$argv[1];$l=$t[+$r++])for($c=~0;$c++<$r*2;)$t[+$r][$c]=$r|$c?$t[$r-2][$c-2]+$l[$c]+$l[$c-1]+$l[$c-2]:1;echo$l[$argv[2]];

オンラインでお試しください!


そして実際にそれを改善するために+1 :)
Uriel


3

MATL22 20 19バイト

Ti:"2Y6Y+FT_Y)]!i_)

両方の入力は0ベースです。

オンラインでお試しください!

説明

させrc、それぞれ、0系行と列を指定する、2つの入力を示します。

Pascalの菱形の各新しい行は、カーネルと畳み込み[1 1 1; 0 1 0]、結果の最後の2行をスワップしたままにすることで、前の2行を含むマトリックスから構築できます。これはr、matrixから数回行われ1ます。

カーネルを使用する方が短いことが判明 [0 1 0; 1 1 1; 0 1 0]事前定義されたリテラルであるわかりました。これにより、余分な行が生成され、破棄されます。

たとえばを検討してください。r = 3したがって、3反復があります。

  1. から始まる

    1
    

    畳み込みが[0 1 0; 1 1 1; 0 1 0]できます

    0 1 0
    1 1 1
    0 1 0
    

    最後の2行(この場合はマトリックス全体)を保持し、それらを交換すると、

    0 1 0
    1 1 1
    
  2. 上記の畳み込み[0 1 0; 1 1 1; 0 1 0]

    0 0 1 0 0
    0 1 1 1 0
    1 2 4 2 1
    0 1 1 1 0
    

    交換された最後の2行で形成される行列は

    0 1 1 1 0
    1 2 4 2 1
    

    これには、下部に新しい行が含まれ、前の行がゼロで拡張されています。

  3. 再び畳み込むと

    0 0 1 1 1 0 0
    0 1 2 3 2 1 0
    1 3 8 9 8 3 1
    0 1 2 4 2 1 0
    

    最後の2行を入れ替えると、

    0 1 2 4 2 1 0
    1 3 8 9 8 3 1
    

後のr反復が行われている、出力は、最終的な行列の最後の行に含まれています。たとえば、c = 2(0から始まる)結果はになります8。最後の行と目的の列にインデックスを付ける代わりに、各行の対称性を活用するトリックを使用できます。最終的な行列が転置されます

0 1
1 3
2 8
4 9
2 8
1 3
0 1

そして、その-c-th要素が取られます。これは線形インデックスを使用します。つまり、マトリックスは列優先の順序で単一のインデックスによってインデックス付けされます。インデックスはモジュール式であるため、0-entryは右下隅(value 1)であり、-2-thエントリは2つ上のステップ(value 8)です。

T       % Push true
i       % Input row number
:"      % Do the following that many times
  2Y6   %   Push predefined literal [0 1 0; 1 1 1; 0 1 0]
  Y+    %   2D convolution, increasing size
  FT_   %   Push [0 -1]
  Y)    %   Matrix with rows 0 (last) and -1 (second-last), in that order
]       % End
!       % Transpose
i       % Input: colun number
_       % Negate
)       % Entry with that index. Implicitly display



2

Mathematica、56バイト

If[#<1,Boole[##==0],Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]]&

2つの整数引数(最初の行、2番目の列)を取り、整数を返す純粋な関数。負の整数引数に対しても機能し、を返し0ます。非常に簡単な再帰構造:If[#<1,Boole[##==0],...]0行目(およびそれ以上)の基本ケースの動作をSum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]定義し、再帰定義を実装します。



1

JavaScript(ES6)、68バイト

f=(y,x)=>x<0|x>y+y?0:x>0&x<y+y?f(--y,x)+f(y,--x)+f(y,--x)+f(--y,x):1


0

Pythonの382の 84バイト

これは、インデックスが1の行と列を持つ再帰的な実装です。(技術的にはf=、84バイトに変更する必要があるかどうかを誰かに知らせてくれることです。まだ新しく、ルールが100%確実ではありません。)

これは、OEISページにある再帰式を使用しますが、をk1つ左にシフトして適切に整列します。偶然にも、sum(f(n-1,k-i)for i in(0,1,2))と同じサイズf(n-1,k)+f(n-1,k-1)+f(n-1,k-2)です。全体の機能は、Pythonであり、and orkは三角形の内側にある場合は、最初の条件をチェックトリック、及び再帰式が使用される場合には境界上にはありません。でない場合には、後の部分がorあれば、そのチェックを返されkている(1, 2*n-1)帰国、境界上すなわち、TrueFalsek+1in(2,2*n)は、より1バイト短いk in(1,2*n-1)。括弧で囲み、+先頭にを置くと、整数に変換されます。これは必要なことです。

f=lambda n,k:2*n-1>k>1and sum(f(n-1,k-i)for i in(0,1,2))+f(n-2,k-2)or+(k+1in(2,2*n))

オンラインでお試しください!


再帰関数にはが必要f=です。
小麦ウィザード

このいくぶん埋もれたメタコンセンサスによると、私は個人的には反対しますが、Pythonのように振る舞うため、True代わりに出力することもできます。これにより、最後にを削除できます。出力を少し奇妙に見えるようにするため、これを行いたくない場合は理解しています。これはオプションです。11+(...)
小麦ウィザード

@WheatWizardうわー、それは非常に興味深いです。ヒントをありがとう。
Cマカヴォイ


0

Python 3 3、75バイト

これは、列と行を0のインデックス付き整数として取る再帰的なラムダです。

p=lambda r,c:(r<0 or((c==0)|p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

印刷機能を備えた(少し)読みやすいバージョンを次に示します。

p = lambda r,c:(r<0 or ((c==0) | p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

def pp(r):
    ml = len(str(p(r,r)))+1
    for i in range(0, r):
            a=" "*ml*(r-i)
            for j in range(0,i*2 + 1):
                    a+=str(p(i,j))+(" "*(ml-len(str(p(i,j)))))
            print(a)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.