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

„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
}<>

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[]

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!



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.


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)

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!


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.