Trójkąt Seidela

14

Trójkąt Seidela jest konstrukcją matematyczną podobną do Trójkąta Pascala i jest znany z połączenia z liczbami Bernoulliego.

Pierwsze kilka wierszy to:

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

Każdy wiersz jest generowany w następujący sposób:

Jeśli numer wiersza jest parzysty (indeksowany 1):

  • Opuść pierwszy element z poprzedniego rzędu

  • Każdy następny element jest sumą poprzedniego elementu i elementu nad nim

  • Zduplikuj ostatni element

Jeśli numer wiersza jest nieparzysty:

  • Opuść ostatni element poprzedniego rzędu

  • Cofając się , każdy element jest sumą poprzedniego elementu i elementu nad nim

  • Zduplikuj pierwszy element.

Zasadniczo budujemy trójkąt w zygzakowaty wzór:

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

Aby uzyskać więcej informacji, zobacz stronę w Wikipedii na temat liczb Bernoulli.

Wyzwanie:

Biorąc pod uwagę n, albo jako argument funkcji, albo z STDIN, wypisz lub zwróć albo nth wiersz trójkąta Seidela, albo pierwszyn rzędy. Możesz użyć indeksowania 0 lub 1.

Nie musisz obsługiwać danych wejściowych ujemnych lub niecałkowitych (ani 0, jeśli indeksowane 1). Nie musisz obsługiwać wyników większych niż2147483647 = 2^31 - 1

Ponieważ jest to kod-golf, zrób to w jak najmniejszej liczbie bajtów.

Przykłady:

W tych przykładach zwracaną wartością jest nth wiersz z indeksowaniem 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
Bolce Bussiere
źródło
„Nie musisz obsługiwać danych wyjściowych większych niż domyślny typ int języka” sprawia, że ​​jest to trywialne dla języków z tylko 1-bitowymi intami
tylko ASCII,
Czy rzędy mogą być zawsze sortowane od małych do dużych?
Angs
@ Tylko ASCII Zmieniono, aby pasowała do maksymalnej int C ++
Bolce Bussiere
@Angs Nie, rzędy należy zamówić jak pokazano
Bolce Bussiere,
@ Tylko ASCII To jest domyślna luka (chociaż IMO jest nieco źle sformułowana, ponieważ zależy od tego, co ludzie uznaliby za „rozsądne”)
202729

Odpowiedzi:

7

Brain-Flak , 66 bajtów

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

Wypróbuj online!

Wiersz jest indeksowany 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
źródło
4

JavaScript (SpiderMonkey) , 67 bajtów

Ten kod narusza sort() metodę i nie działa we wszystkich silnikach.

Rzędy są indeksowane na 0.

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

Wypróbuj online!

W jaki sposób?

Warunkowo odwracamy tablicę za pomocą sort()metody z funkcją wywołania zwrotnego, która ignoruje jej parametry i zwraca wartość 0 lub dodatnią liczbę całkowitą. Nie próbuj tego w domu! Działa to niezawodnie tylko w przypadku 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

Zauważ, że V8 prawdopodobnie używa różnych algorytmów sortowania w zależności od długości tablicy (mniej lub więcej niż 10 elementów).

Skomentował

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
źródło
Z jakiej funkcji specyficznej dla małp pająka korzysta ta funkcja?
Downgoat
@Downgoat Wykorzystuje specyficzną implementację sort()tego silnika. Dodałem wyjaśnienie.
Arnauld,
3

Haskell , 89 87 82 bajtów

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

Po prostu sdrukuje linie w kolejności zygzakowatej, anonimowa funkcja w pierwszym rzędzie odwraca połowę wierszy.

Dzięki @nimi za uratowanie 5 bajtów!

Wypróbuj online!

Angs
źródło
2

Python 3 , 98 91 bajtów

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

Wypróbuj online!

Przejście do numerowania wierszy opartego na 0 pozwoliło zaoszczędzić 7 bajtów.

RootTwo
źródło
2

Julia 0.6 , 85 bajtów

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

Wypróbuj online!

To jest rekurencyjne rozwiązanie w Julii. Zauważ, że ma indeksowanie 1. Stąd testy.

Wersja bez golfa, aby zrozumieć logikę:

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

Jako bonus, oto wersja nierekurencyjna, ale jest to dłużej:

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
źródło
1

Python 2 , 103 97 bajtów

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]

Wypróbuj online!

Wersja nierekurencyjna (łatwiejsza do odczytania):

Python 2 , 106 bajtów

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]

Wypróbuj online!

Z pewnością jest to możliwe!

Chas Brown
źródło
1

Python 3 , 91 bajtów

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

Wypróbuj online!

Guoyang Qin
źródło
Możesz usunąć odstęp między importi*
maja 21