Triangolo di Seidel


14

Il Triangolo di Seidel è una costruzione matematica simile al Triangolo di Pascal, ed è noto per la sua connessione con i numeri di Bernoulli.

Le prime poche righe sono:

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

Ogni riga viene generata come segue:

Se il numero di riga è pari (1 indicizzato):

  • Elimina il primo elemento della riga precedente

  • Ogni articolo successivo è la somma dell'articolo precedente e dell'articolo sopra di esso

  • Duplica l'ultimo elemento

Se il numero di riga è dispari:

  • Elimina l'ultimo elemento della riga precedente

  • Andando indietro , ogni articolo è la somma dell'articolo precedente e dell'articolo sopra di esso

  • Duplica quello che ora è il primo oggetto.

Fondamentalmente, costruiamo il triangolo in uno schema a zig-zag:

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

Per ulteriori informazioni, consultare la pagina Wikipedia sui numeri di Bernoulli.

La sfida:

Dato n, come argomento di funzione o da STDIN, stampa o restituisce la nriga del triangolo di Seidel o le prime nrighe. È possibile utilizzare l'indicizzazione 0 o 1.

Non è necessario gestire input negativi o non interi (né 0, se 1-indicizzato). Non è necessario gestire output più grandi di2147483647 = 2^31 - 1

Dato che si tratta di code-golf, fallo nel minor numero di byte possibile.

Esempi:

In questi esempi il valore restituito è la nriga th, indicizzata 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

"Non è necessario gestire output più grandi del tipo int predefinito della propria lingua" rende questo aspetto banale per le lingue con solo 1 bit di bit
solo ASCII il

Le righe possono essere emesse sempre ordinate da piccole a grandi?
Angs

@ Solo ASCII Modificato per corrispondere al massimo int di C ++
Bolce Bussiere,

@Angs No, le file devono essere ordinate come mostrato
Bolce Bussiere,

@ ASCII-only Questa è una scappatoia predefinita (anche se IMO è un po 'mal formulata in quanto dipende da ciò che la gente considererebbe "ragionevole")
user202729

Risposte:


7

Brain-Flak , 66 byte

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

Provalo online!

La riga è indicizzata 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 byte

Questo codice abusa del sort()metodo e non funziona su tutti i motori.

Le righe sono indicizzate 0.

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

Provalo online!

Come?

Invertiamo condizionalmente un array utilizzando il sort()metodo con una funzione di callback che ignora i suoi parametri e restituisce 0 o un numero intero positivo. Non provarlo a casa! Funziona in modo affidabile solo su 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

Si noti che V8 probabilmente utilizza algoritmi di ordinamento diversi a seconda della lunghezza dell'array (inferiore o superiore a 10 elementi).

Commentate

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

Quale caratteristica specifica di ragno-scimmia usa questo?
Downgoat,

@Downgoat Sta sfruttando l'implementazione specifica di sort()questo motore. Ho aggiunto una spiegazione.
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

sStampa solo le linee nell'ordine di zig-zag, la funzione anonima sulla prima riga inverte la metà delle righe.

Grazie a @nimi per aver salvato 5 byte!

Provalo online!



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]

Provalo online!

Il passaggio alla numerazione delle righe in base 0 ha salvato 7 byte.


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

Provalo online!

Questa è una soluzione ricorsiva in Julia. Si noti che ha l'indicizzazione basata su 1. Da qui i test.

Versione non golfata, per comprendere la logica:

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

Come bonus, ecco una versione non ricorsiva, ma questa è più lunga:

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

Provalo online!

Versione non ricorsiva (più facile da leggere):

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]

Provalo online!

Sicuramente, meglio è possibile!


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.