Segitiga Seidel

14

Segitiga Seidel adalah konstruksi matematika yang mirip dengan Segitiga Pascal, dan dikenal karena hubungannya dengan angka Bernoulli.

Beberapa baris pertama adalah:

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

Setiap baris dihasilkan sebagai berikut:

Jika nomor baris genap (1-diindeks):

  • Turunkan item pertama dari baris sebelumnya

  • Setiap item berikutnya adalah jumlah dari item sebelumnya dan item di atasnya

  • Gandakan item terakhir

Jika nomor barisnya ganjil:

  • Turunkan item terakhir dari baris sebelumnya

  • Ke belakang , setiap item adalah jumlah dari item sebelumnya dan item di atasnya

  • Gandakan apa yang sekarang menjadi item pertama.

Pada dasarnya, kita membangun segitiga dalam pola zig-zag:

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

Untuk informasi lebih lanjut, lihat halaman Wikipedia tentang nomor Bernoulli.

Tantangan:

Diberikan n, baik sebagai argumen fungsi atau dari STDIN, cetak atau kembalikan nbaris th dari segitiga Seidel atau nbaris pertama . Anda dapat menggunakan pengindeksan 0 atau 1.

Anda tidak perlu menangani input negatif atau non-integer (atau 0, jika 1-diindeks). Anda tidak harus menangani keluaran yang lebih besar dari2147483647 = 2^31 - 1

Karena ini adalah kode-golf, lakukan ini dalam byte sesedikit mungkin.

Contoh:

Dalam contoh ini nilai kembali adalah nbaris ke-0, diindeks.

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
Bolce Bussiere
sumber
"Anda tidak harus menangani output yang lebih besar dari tipe int standar bahasa Anda" menjadikan ini sepele untuk bahasa hanya dengan int 1-bit
ASCII
Bisakah baris yang dihasilkan selalu diurutkan dari kecil ke besar?
Angs
@ Khusus ASCII Diubah agar sesuai dengan int maksimum C ++
Bolce Bussiere
@Angs Tidak, baris harus dipesan seperti yang ditunjukkan
Bolce Bussiere
@ Khusus ASCII Itu adalah celah default (meskipun IMO itu agak buruk karena tergantung pada apa yang orang anggap "masuk akal")
user202729

Jawaban:

7

Brain-Flak , 66 byte

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

Cobalah online!

Baris diindeks 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
}<>
Nitrodon
sumber
4

JavaScript (SpiderMonkey) , 67 byte

Kode ini menyalahgunakan sort()metode dan tidak bekerja di semua mesin.

Baris diindeks 0.

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

Cobalah online!

Bagaimana?

Kami membalikkan array dengan menggunakan sort()metode dengan fungsi callback yang mengabaikan parameternya dan mengembalikan 0 atau bilangan bulat positif. Jangan coba ini di rumah! Ini hanya berfungsi dengan baik pada 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

Perhatikan bahwa V8 mungkin menggunakan algoritma pengurutan yang berbeda tergantung pada panjang array (kurang dari 10 elemen).

Berkomentar

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[]
Arnauld
sumber
Fitur spesifik spider-monkey apa yang digunakan ini?
Downgoat
@Downgoat Ini mengambil keuntungan dari implementasi spesifik sort()di mesin ini. Saya telah menambahkan penjelasan.
Arnauld
3

Haskell , 89 87 82 byte

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

Hanya s mencetak garis dalam urutan zig-zag, fungsi anonim di baris pertama membalikkan setengah dari baris.

Terima kasih kepada @nimi karena telah menghemat 5 byte!

Cobalah online!

Angs
sumber
2

Python 3 , 98 91 byte

from itertools import*
f=lambda n:n and[*accumulate(f(n-1)[::n&1or-1]+[0])][::n&1or-1]or[1]

Cobalah online!

Beralih ke penomoran baris berbasis 0 menghemat 7 byte.

RootTwo
sumber
2

Julia 0,6 , 85 byte

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

Cobalah online!

Ini adalah solusi rekursif di Julia. Perhatikan bahwa ini memiliki pengindeksan berbasis 1. Karena itu tes.

Versi tidak disatukan, untuk memahami logika:

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

Asa bonus, ini versi non-rekursif, tapi ini lebih lama:

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)
niczky12
sumber
1

Python 2 , 103 97 byte

f=lambda n,r=[1],k=2:n and f(n-1,[sum(r[-2::-1][:i],r[-1])for i in range(k)],k+1)or r[::-(-1)**k]

Cobalah online!

Versi non-rekursif (lebih mudah dibaca):

Python 2 , 106 byte

def f(n,r=[1],j=1):
 while n:
	a=r[-2::-1];r=r[-1:];n-=1;j=-j
	for x in a+[0]:r+=[r[-1]+x]
 return r[::-j]

Cobalah online!

Tentunya, lebih baik mungkin!

Chas Brown
sumber
1

Python 3 , 91 byte

from numpy import *
s=lambda n:n and cumsum(s(n-1)[::n%2*2-1]+[0]).tolist()[::n%2*2-1]or[1]

Cobalah online!

Guoyang Qin
sumber
Anda dapat menghapus ruang antara importdan*
12Me21