ザイデルトライアングル


14

ザイデル三角形は、パスカルの三角形に似た数学的構造であり、ベルヌーイ数との関係で知られています。

最初の数行は次のとおりです。

      1
      1  1
   2  2  1
   2  4  5  5
16 16 14 10 5
16 32 46 56 61 61

各行は次のように生成されます。

行番号が偶数(1から始まる)の場合:

  • 前の行の最初のアイテムを停止します

  • 次のすべてのアイテムは、前のアイテムとその上のアイテムの合計です

  • 最後のアイテムを複製する

行番号が奇数の場合:

  • 前の行の最後のアイテムを停止する

  • 後方に行くと、各アイテムは前のアイテムとその上のアイテムの合計です

  • 現在の最初のアイテムを複製します。

基本的に、三角形をジグザグパターンで作成します。

    1
    v
    1 > 1
        v
2 < 2 < 1
v
2 > 4 > 5 > 5

詳細についてはベルヌーイ数に関するウィキペディアのページを参照してください

チャレンジ:

与えられたn関数の引数として、またはSTDIN、プリントまたはリターンのいずれかのいずれかから、nザイデル三角形または最初の行目nの行。0または1のインデックスを使用できます。

負の入力または非整数の入力を処理する必要はありません(1がインデックス付けされている場合は0もありません)。より大きい出力を処理する必要はありません2147483647 = 2^31 - 1

これはコードゴルフなので、できるだけ少ないバイトでこれを行います。

例:

これらの例では、戻り値はn0番目の行の0インデックスです。

Input   ->  Output

0           1
1           1 1
2           2 2 1
6           272 272 256 224 178 122 61
13          22368256 44736512 66750976 88057856 108311296 127181312 144361456 159575936 172585936 183194912 191252686 196658216 199360981 199360981

唯一の1ビットのint型を持つ言語のために、これは些細な作る「あなたはあなたの言語のデフォルトのint型よりも大きな出力を処理する必要がありません」
ASCIIのみ

行を常に小から大にソートして出力できますか?
アンス


示すようにノー@Angs、行を注文しなければならない
Bolce Bussiere

回答:


7

Brain-Flak、66バイト

<>(())<>{({}[()]<(()[{}]<<>{(({}<>{}))<>}>)>)}{}{{}<>{({}<>)<>}}<>

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

行のインデックスは0です。

# Push 1 (the contents of row 0) on other stack; use implicit zero as parity of current row
<>(())<>

# Do a number of times equal to input:
{({}[()]<

  # Subtract the row parity from 1
  (()[{}]<

    # For each entry in old row:
    <>{

      # Add to previous entry in new row and push twice
      (({}<>{}))<>

    }

  >)

>)}{}

# If row parity is odd:
{{}

  # Reverse stack for output
  <>{({}<>)<>}

# Switch stacks for output
}<>

4

JavaScript(SpiderMonkey)、67バイト

このコードはsort()メソッドを悪用し、すべてのエンジンで機能するわけではありません。

行のインデックスは0です。

f=(n,a=[1],r)=>n--?f(n,[...a.map(n=>k+=n,k=0),k].sort(_=>n|r),!r):a

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

どうやって?

sort()パラメータを無視し、0または正の整数を返すコールバック関数を含むメソッドを使用して、条件付きで配列を反転します。自宅でこれを試さないでください!これは、SpiderMonkeyでのみ確実に機能します。

let A = [1,2,3,4,5] and B = [1,2,3,4,5,6,7,8,9,10,11]

             | SpiderMonkey (Firefox)  | V8 (Chrome)             | Chakra (Edge)
-------------+-------------------------+-------------------------+------------------------
A.sort(_=>0) | 1,2,3,4,5               | 1,2,3,4,5               | 1,2,3,4,5
A.sort(_=>1) | 5,4,3,2,1               | 5,4,3,2,1               | 1,2,3,4,5
B.sort(_=>0) | 1,2,3,4,5,6,7,8,9,10,11 | 6,1,3,4,5,2,7,8,9,10,11 | 1,2,3,4,5,6,7,8,9,10,11
B.sort(_=>1) | 11,10,9,8,7,6,5,4,3,2,1 | 6,11,1,10,9,8,7,2,5,4,3 | 1,2,3,4,5,6,7,8,9,10,11

V8は、おそらく配列の長さ(10エレメント以下)に応じて異なるソートアルゴリズムを使用していることに注意してください。

コメント済み

f = (                     // f = recursive function taking:
  n,                      //   n   = row counter
  a = [1],                //   a[] = current row, initialized to [1]
  r                       //   r   = 'reverse' flag, initially undefined
) =>                      //
  n-- ?                   // decrement n; if it was not equal to zero:
    f(                    //   do a recursive call with:
      n,                  //     - the updated value of n
      [ ...a.map(n =>     //     - a new array:
          k += n, k = 0   //       - made of the cumulative sum of a[]
        ), k              //         with the last value appended twice
      ].sort(_ => n | r), //       - reversed if n is not equal to 0 or r is set
      !r                  //     - the updated flag r
    )                     //   end of recursive call
  :                       // else:
    a                     //   stop recursion and return a[]

これはどのようなクモザル固有の機能を使用しますか?
ダウンゴート

@Downgoat sort()このエンジンでの特定の実装を利用しています。説明を追加しました。
アーナウルド


3

Haskell89 87 82バイト

(cycle[r,id]!!)<*>s
r=reverse
s 0=[1]
s n=let a=zipWith(+)(0:a)$(r.s$n-1)++[0]in a

s行をジグザグ順に印刷するだけで、最初の行の匿名関数は行の半分を反転します。

5バイトを節約してくれた@nimiに感謝します!

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




2

ジュリア0.6、85バイト

r(l,n=cumsum(l))=[n...,n[end]]
w=reverse
f(n)=n<2?[1]:n%2<1?r(f(n-1)):w(r(w(f(n-1))))

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

これは、ジュリアの再帰的なソリューションです。1ベースのインデックス付けがあることに注意してください。したがって、テスト。

ロジックを理解するためのゴルフのないバージョン:

function new_row(last_row)
    new_row = cumsum(last_row)
    push!(new_row, new_row[end])
    return new_row
end


function triangle(n)
    if n == 1
        return [1]
    elseif mod(n,2) == 0
        return new_row(triangle(n-1))
    else
        return reverse(new_row(reverse(triangle(n-1))))
    end
end

ボーナスとして、ここに非再帰バージョンがありますが、これはもっと長いです:

w=reverse;c=cumsum
r(l,i)=i%2<1?c([l...,0]):w(c(w([0,l...])))
f(n,l=[1])=(for i=2:n l=r(l,i)end;l)


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.