Triangolo di Pascal (sorta di)


24

Quasi tutti qui conoscono il triangolo di Pascal. È formato da file successive, dove ogni elemento è la somma dei suoi due vicini in alto a sinistra e in alto a destra. Ecco le prime 5righe (prese in prestito dal triangolo di Generate Pascal ):

    1
   1 1
  1 2 1
 1 3 3 1
1 4 6 4 1
  . . .

Comprimi queste righe a sinistra

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
. . .

Ordinali in ordine crescente

1
1 1
1 1 2
1 1 3 3
1 1 4 4 6
. . .

Leggi questo triangolo per righe

[1, 1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 4, 6 ...]

Dato un input n, genera il nnumero th in questa serie. Questo è OEIS 107430 .

Regole

  • È possibile scegliere l'indicizzazione basata su 0 o 1. Si prega di indicare quale nella vostra presentazione.
  • Si può presumere che l'input e l'output si adattino al tipo intero nativo della tua lingua.
  • L'input e l'output possono essere forniti con qualsiasi metodo conveniente .
  • È accettabile un programma completo o una funzione. Se una funzione, è possibile restituire l'output anziché stamparlo.
  • Sono vietate le scappatoie standard .
  • Si tratta di quindi si applicano tutte le normali regole del golf e vince il codice più breve (in byte).

6
Titolo molto bello!
Luis Mendo,

1
Come per il collegamento OEIS, l'unica modifica richiesta per generare questa sequenza invece di un coefficiente binomiale è una divisione intera. Ciò rientra certamente in "banale".
Peter Taylor,

5
@PeterTaylor Questo non mi sembra un ovvio ingannevole. Ci sono molti altri approcci possibili che possono portare a interessanti opportunità di golf, specialmente per le lingue che non hanno un binomio incorporato.
Arnauld,

4
@PeterTaylor Non sono convinto che questo sia un duplicato. Finora, le risposte MATL, JavaScript e Pascal sono piuttosto diverse tra le due sfide. Tuttavia, poiché il mio voto è aperto, non voterò ancora.
AdmBorkBork,

4
Totalmente d'accordo con @AdmBorkBork. Quindi contami come riaprire il voto. Questo fa 3 ora. Quanti voti sono necessari per la riapertura?
Luis Mendo,

Risposte:


9

JavaScript (ES6), 79 byte

0-indicizzati.

f=(n,a=[L=1])=>a[n]||f(n-L,[...a.map((v,i)=>k=(x=v)+~~a[i-1-i%2]),L++&1?k:2*x])

dimostrazione

Come?

f = (                       // f = recursive function taking:
  n,                        //   n = target index
  a = [L = 1]               //   a[] = current row, L = length of current row
) =>                        //
  a[n] ||                   // if a[n] exists, stop recursion and return it
  f(                        // otherwise, do a recursive call to f() with:
    n - L,                  //   n minus the length of the current row
    [                       //   an array consisting of:
      ...a.map((v, i) =>    //     replace each entry v at position i in a[] with:
        k =                 //       a new entry k defined as:
        (x = v) +           //       v +
        ~~a[i - 1 - i % 2]  //       either the last or penultimate entry
      ),                    //     end of map()
      L++ & 1 ?             //     increment L; if L was odd:
        k                   //       append the last updated entry
      :                     //     else:
        2 * x               //       append twice the last original entry
    ]                       //   end of array update
  )                         // end of recursive call

Questo algoritmo genera direttamente le righe ordinate del Triangolo di Pascal. Aggiorna n in base alla lunghezza della riga precedente finché non esiste un [n] . Ad esempio, sono necessarie 6 iterazioni per n = 19 :

 L | n  | a[]
---+----+------------------------
 1 | 19 | [ 1 ]
 2 | 18 | [ 1, 1 ]
 3 | 16 | [ 1, 1, 2 ]
 4 | 13 | [ 1, 1, 3, 3 ]
 5 |  9 | [ 1, 1, 4, 4, 6 ]
 6 |  4 | [ 1, 1, 5, 5, 10, 10 ]
                        ^^

Bel lavoro. Non sono sicuro se capisco esattamente come funziona però. Il mio tentativo si è rivelato molto più lungo del tuo.
kamoroso94,

@ kamoroso94 Ho aggiunto una spiegazione.
Arnauld

Amo questo! Mi è davvero piaciuto capire cosa stesse facendo.
Shaggy

6

Ottava , 46 byte

@(n)(M=sort(spdiags(flip(pascal(n)))))(~~M)(n)

1-based.

Provalo online!

Spiegazione

Considera n=4come esempio.

pascal(n) dà una matrice Pascal:

 1     1     1     1
 1     2     3     4
 1     3     6    10
 1     4    10    20

Le file del triangolo pasquale sono gli antidiagonali di questa matrice. Quindi viene capovolto verticalmente usandoflip(···)

 1     4    10    20
 1     3     6    10
 1     2     3     4
 1     1     1     1

che trasforma gli antidiagonali in diagonali.

spdiags(···) estrae le diagonali (diverse da zero), iniziando da in basso a sinistra, e le dispone come colonne a zero:

 1     1     1     1     0     0     0
 0     1     2     3     4     0     0
 0     0     1     3     6    10     0
 0     0     0     1     4    10    20

M=sort(···)ordina ogni colonna di questa matrice e assegna il risultato alla variabile M:

 0     0     0     1     0     0     0
 0     0     1     1     4     0     0
 0     1     1     3     4    10     0
 1     1     2     3     6    10    20

L'indicizzazione logica (···)(~~M)ora viene utilizzata per estrarre i nonzeros di questa matrice in ordine di colonna maggiore (verso il basso, quindi attraverso). Il risultato è un vettore di colonna:

 1
 1
 1
 1
···
10
10
20

Infine, nviene estratta la nona voce di questo vettore (···)(n), che in questo caso dà 1.


5

Python 2 , 86 78 72 byte

-8 byte grazie a Rod

g=lambda n,r=[1]:r[n:]and r[n/2]or g(n-len(r),map(sum,zip([0]+r,r+[0])))

Provalo online!

Ungolfed

def g(n, row=[1]):
  if n < len(row):
    return row[n/2]
  else:
    next_row = map(sum, zip([0] + row, row + [0]))
    return g(n - len(row), next_row)

Provalo online!

La funzione calcola ricorsivamente la riga del triangolo di Pascal. Data la riga corrente come row, map(sum, zip([0] + row, row + [0])).
Ad ogni chiamata nviene ridotta la lunghezza della riga corrente. Se la funzione arriva alla riga destra, nthdeve essere restituito il numero più basso della riga.
Poiché la prima metà di una riga è in ordine crescente e ogni riga è simmetrica, il numero è nell'indice n/2(0-indicizzato, divisione intera).


4

Wolfram Language (Mathematica) , 55 byte

L'indicizzazione è basata su 1.

(##&@@@Sort/@Table[n~Binomial~k,{n,0,#},{k,0,n}])[[#]]&

Provalo online!

Spiegazione

Questo è probabilmente golfabile, non sono un utente Mathematica molto esperto.

Table[n~Binomial~k,{n,0,#},{k,0,n}]

Per ogni n ∈ [0, Input] ∩ ℤ , genera la tabella dei binomi con ogni k ∈ [0, n] ∩ ℤ .

Sort/@

Ordina ciascuno. Usa una scorciatoia per Map[function,object]- function/@object.

(##&@@@...)[[#]]

Appiattire l'elenco risultante e recuperare l'elemento il cui indice nell'elenco è l'input.



3

R , 58 byte

function(n)(m=apply(outer(0:n,0:n,choose),1,sort))[m>0][n]

Provalo online!

Calcola n choose kper ciascuno n,kin [0,1,...,n]una matrice, ordina le righe in ordine crescente (*) e rimuove gli zeri, quindi seleziona iln elemento th.

(*) Questo li trasforma anche in colonne, ma è meglio dal momento che R memorizza una matrice come un vettore a colonne, il che ci consente di indicizzare direttamente in essa preservando l'ordine.


3

Haskell , 143 132 125 123 byte

((p>>=s.h)!!)
p=[1]:map(\r->zipWith(+)(0:r)(r++[0]))p
h r=splitAt(div(length r)2)r
s(a,b)=reverse b!a
(h:t)!b=h:(b!t)
x!_=x

La prima riga è una funzione senza punti che accetta un indice (basato su 0) e restituisce il numero appropriato nella sequenza. Provalo online!

Questo è il mio primo programma Haskell in assoluto! Sono sicuro che può essere molto più breve. I suggerimenti sono apprezzati.

Salvato 2 byte grazie a nimi

Ungolfed

pascalRows = [1] : map (\row -> zipWith (+) (0:row) (row++[0])) pascalRows
halves row = splitAt (div (length row) 2) row
joinSorted (first, second) = interleave (reverse second) first
interleave [] _ = []
interleave longer shorter = (head longer) : (interleave shorter (tail longer))
f n = (concatMap (joinSorted.halves) pascalRows) !! n

Hai ancora iin funzione s, che è stato ribattezzato !, credo. Se si utilizza una funzione di infisso è possibile eliminare il ()giro reverse b: s(a,b)=reverse b!a.
nimi,

@nimi Ah, grazie - L'ho cambiato su TIO ma ho perso un punto sul codice qui. E grazie per il suggerimento tra parentesi.
DLosc

3

JavaScript, 57 byte

f=(i,r=1)=>i<r?i>1?f(i-2,--r)+f(i<r?i:r-1,r):1:f(i-r,r+1)

0-indicizzati.

Come viene:

Step 0:

c=(i,r)=>i?r&&c(i-1,r-1)+c(i,r-1):1
f=(i,r=1)=>i<r?c(i>>1,r-1):f(i-r,r+1)

Questo codice è facile da capire:

  • la funzione ccalcola la formula d'uso Combinazione: C (n, k) = C (n-1, k) + C (n-1, k-1); o 1 se k == 0 o k == n
  • funzione di fcercare di scoprire il numero di riga e l'indice nella riga, e quindi chiamare la funzione C per ottenere il risultato.

Passo 1:

c=(i,r)=>i>1?--r&&c(i-2,r)+c(i,r):1
f=(i,r=1)=>i<r?c(i,r):f(i-r,r+1)

In questo passaggio, proviamo a modificare la chiamata della funzione calla c(i,r)quale diventa uguale al parametro di f.

Passo 2:

c=(i,r)=>i>1?--r&&c(i-2,r)+c(i<r?i:r-1,r):1
f=(i,r=1)=>i<r?c(i,r):f(i-r,r+1)

Testiamo i<rse si utilizza la funzione fo la funzione c. Questo è il motivo per cui il muschio i<rmantiene la presa durante la ricorsione della funzione c.

Passaggio 3:

f=(i,r=1)=>i<r?i>1?--r&&f(i-2,r)+f(i<r?i:r-1,r):1:f(i-r,r+1)

A questo punto, uniamo queste due funzioni in una.

Dopo un altro po 'di golf, abbiamo finalmente ottenuto la risposta sopra descritta.


2

Gelatina , 13 byte

0rcþ`ZṢ€Ẏḟ0⁸ị

Provalo online!

Usando l'algoritmo Dyalog di Uriel.

1-indicizzati.

Spiegazione:

0rcþ`ZṢ€Ẏḟ0⁸ị
0r            Return inclusive range from 0 to n
    `         Call this dyad with this argument on both sides
   þ           Outer product with this dyad
  c             Binomial coefficient
     Z        Zip
       €      Call this link on each element
      Ṣ        Sort
        Ẏ     Concatenate elements
         ḟ0   Remove 0s
           ⁸ị Take the nth element

Potresti aggiungere una spiegazione? Non riesco a capire cosa ci þfaccia qui.
Shaggy,

1
@Shaggy È un prodotto esterno, aggiungerò una spiegazione.
Erik the Outgolfer,

2

JavaScript (Node.js) , 65 byte

Neanche un array viene utilizzato. 0-indicizzati.

f=(n,i=0,g=x=>x?x*g(x-1):1)=>n>i?f(n-++i,i):g(i)/g(c=n>>1)/g(i-c)

Provalo online!

Spiegazione:

f=(n,i=0,                 )=>                                     // Main Function
         g=x=>x?x*g(x-1):1                                        // Helper (Factorial)
                             n>i?                                 // Is n > i?
                                 f(n-++i,i):                      // If so, call function
                                                                  // f(n-i-1, i+1) to skip
                                                                  // . i+1 terms
                                            g(i)/g(c=n>>1)/g(i-c) // If not, since sorting 
                                                                  // . the binomial coeffs
                                                                  // . equals to writing
                                                                  // . the first floor(i/2)
                                                                  // . coefficients twice
                                                                  // . each, so a shortcut

1

Pascal , 373 byte

function t(n,k,r:integer):integer;begin if(n<k)then t:=r-1 else t:=t(n,k+r,r+1)end;
function s(n,k:integer):integer;begin if(k=0)then s:=n else s:=s(n+k,k-1)end;
function f(n,k:integer):integer;begin if((k<1)or(k>n))then f:=0 else if n=1 then f:=1 else f:=f(n-1,k-1)+f(n-1,k)end;
function g(n:integer):integer;var k:integer;begin k:=t(n,0,1);g:=f(k,(n-s(0,k-1)+2)div 2)end;

g è la funzione.

Provalo online!


n=1 thenpuò essere n=1then.
Jonathan Frech,

Allo stesso modo, sembra che if(k=0)thenpossa diventare if k=0then.
Shaggy

se un numero sempre maggiore di 0, è necessario utilizzare wordinvece di integer.
TSH

1

Java 8, 187 byte

n->{int r=~-(int)Math.sqrt(8*n+1)/2+1,a[]=new int[r],k=r,x=0;for(;k-->0;a[k]=p(r,k))x+=k;java.util.Arrays.sort(a);return a[n-x];}int p(int r,int k){return--r<1|k<2|k>r?1:p(r,k-1)+p(r,k);}

Spiegazione:

Provalo online.

n->{                   // Method with integer as both parameter and return-type
  int r=~-(int)Math.sqrt(8*n+1)/2+1,
                       //  Calculate the 1-indexed row based on the input
      a[]=new int[r],  //  Create an array with items equal to the current row
      k=r,             //  Index integer
      x=0;             //  Correction integer
  for(;k-->0;          //  Loop down to 0
    a[k]=p(r,k))       //   Fill the array with the Pascal's Triangle numbers of the row
    x+=k;              //   Create the correction integer
  java.util.Arrays.sort(a);
                       //  Sort the array
  return a[n-x];}      //  Return the `n-x`'th (0-indexed) item in this sorted array

// Separated recursive method to get the k'th value of the r'th row in the Pascal Triangle
int p(int r,int k){return--r<1|k<2|k>r?1:p(r,k-1)+p(r,k);}

1

MATL , 11 byte

:qt!XnSXzG)

1-based.

Provalo online! O verifica tutti i casi di test .

Spiegazione

Considera l'input 4come esempio. ;è il separatore di riga per matrici o vettori di colonna.

:     % Implicit input: n. Push the row vector [1 2 ... n]          
      S STACK: [1 2 3 4]
q     % Subtract 1, emlement-wise: gives [0 1 ... n-1]
      % STACK: [0 1 2 3]
t!    % Duplicate and transpose into a column vector
      % STACK: [0 1 2 3], [0; 1; 2; 3]
Xn    % Binomial coefficient, element-wise with broadcast. Gives an
      % n×n matrix where entry (i,j) is binomial(i,j), or 0 for i<j
      % STACK: [1 1 1 1;
                0 1 2 3;
                0 0 1 3;
                0 0 0 1]
S     % Sort each column
      % STACK: [0 0 0 1;
      %         0 0 1 1;
      %         0 1 1 3;
      %         1 1 2 3]
Xz    % Keep only nonzeros. Gives a column vector
      % STACK: [1; 1; 1; 1; 1; 2; 1; 1; 3; 3]
G)    % Get the n-th element. Implicitly display
      % STACK: 1

1

Lotto, 128 byte

@set/as=2,t=r=m=i=1
:l
@if %1 geq %t% set/as+=r,t+=r+=1&goto l
@for /l %%i in (%s%,2,%1)do @set/ar-=1,m=m*r/i,i+=1
@echo %m%

0-indicizzati.


Puoi aggiungere una spiegazione, per favore? Non riesco proprio a seguire la logica qui.
AdmBorkBork,

@AdmBorkBork Le prime tre righe calcolano la riga re la colonna %1-(s-2)del %1th della serie. La quarta riga utilizza quindi quella per calcolare il coefficiente binomiale (n k) = n!/(n-k)!k!= n(n-1)...(n+1-k)/(1)(2)...k= (n/1)((n-1)/2)...((n+1-k)/k). Dov'è MathJax quando ne ho bisogno?
Neil,

1

APL (Dyalog Classic) , 17 byte

⎕⊃∊i!⍨,\⌊.5×i←⍳99

Provalo online!

Indicizzazione basata su 0

si noti che (49!98) > 2*53, cioè il coefficiente binomiale 98 su 49 è maggiore di 2 53 , quindi a quel punto Dyalog ha già iniziato a perdere precisione a causa del virgola mobile IEEE


@Abigail vedi qui e qui
ngn

1

05AB1E , 10 byte

0-indicizzato

ÝεDÝc{}˜sè

Provalo online!

Spiegazione

Ý             # push range [0 ... input]
 ε    }       # apply to each element
  DÝc         # N choose [0 ... N]
     {        # sort
       ˜      # flatten result to a list
        sè    # get the element at index <input>

1

Gelatina , 11 byte

Ḷc€`Ṣ€Fḟ0ị@

Provalo online!

Un collegamento monadico che prende l'indice e restituisce un numero intero - utilizza l'indicizzazione basata su 1.

Come?

Esegue la sfida praticamente come è stata scritta, solo con più del triangolo di Pascal (zeri) che viene poi gettato via ...

Ḷc€`Ṣ€Fḟ0ị@ - Link: integer, i    e.g. 1   or    9
Ḷ           - lowered range            [0]       [0,1,2,3,4,5,6,7,8]
   `        - repeat left as right arg [0]       [0,1,2,3,4,5,6,7,8]
 c€         - binomial choice for €ach [[1]]     [[1,0,0,0,0,0,0,0,0],[1,1,0,0,0,0,0,0,0],[1,2,1,0,0,0,0,0,0],[1,3,3,1,0,0,0,0,0],[1,4,6,4,1,0,0,0,0],[1,5,10,10,5,1,0,0,0],[1,6,15,20,15,6,1,0,0],[1,7,21,35,35,21,7,1,0],[1,8,28,56,70,56,28,8,1]]
    Ṣ€      - sort €ach                [[1]]     [[0,0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,1,1],[0,0,0,0,0,0,1,1,2],[0,0,0,0,0,1,1,3,3],[0,0,0,0,1,1,4,4,6],[0,0,0,1,1,5,5,10,10],[0,0,1,1,6,6,15,15,20],[0,1,1,7,7,21,21,35,35],[1,1,8,8,28,28,56,56,70]]
      F     - flatten                  [1]       [0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,2,0,0,0,0,0,1,1,3,3,0,0,0,0,1,1,4,4,6,0,0,0,1,1,5,5,10,10,0,0,1,1,6,6,15,15,20,0,1,1,7,7,21,21,35,35,1,1,8,8,28,28,56,56,70]
       ḟ0   - filter discard zeros     [1]       [1,1,1,1,1,2,1,1,3,3,1,1,4,4,6,1,1,5,5,111,1,6,6,15,15,21,1,7,7,21,21,35,35,1,1,8,8,28,28,56,56,70]
         ị@ - index into (sw@p args)    1         3 --------------^

1

Rosso , 206 byte

f: func[n][t: copy[[1]]l: 0
while[l < n][a: copy last t insert append a 0 0 b: copy[]repeat i k:(length? a)- 1[append b a/(i) + a/(i + 1)]append t reduce[b]l: l + k]foreach p t[sort p]pick split form t{ }n]

1-based

Provalo online!

Spiegazione:

f: func [n] [
    t: copy [[1]]                       ; start with a list with one sublist [1]
    l: 0                                ; there are 1 items overall
    while [l < n] [                     ; while the number of items is less than the argument
        a: copy last t                  ; take the last sublist 
        insert append a 0 0             ; prepend and append 0 to it  
        b: copy []                      ; prepare a list for the sums  
        repeat i k: (length? a) - 1 [   ; loop throught the elements of the list
            append b a/(i) + a/(i + 1)] ; and find the sum of the adjacent items
        append t reduce [b]             ; append the resulting list to the total list
        l: l + k                        ; update the number of the items
    ]
    foreach p t [sort p]                ; sort each sublist
    v: pick split form t { } n          ; flatten the list and take the n-th element
]

1

Perl, 48 byte

Include +1perp

perl -pe '$_-=$%until$_<++$%;$./=$_/--$%for 1..$_/2;$_=$.' <<< 19

Utilizza l'indicizzazione di base 0.


1

J, 46 41 byte

f=:](([-2!]){/:~@(i.!<:)@])[:<.2&!@,:^:_1

0-indicizzato

Provalo online!

Gli appunti:

  • <.2&!@,:^:_1 fornisce il numero di riga pertinente del triangolo di Pascal arrotondando per difetto l'inverso di y choose 2 .
  • /:~@(i.!<:)@] calcola la riga e la ordina.
  • [-2!] fornisce l'indice nella riga.

Ciao. Benvenuti nel sito! Questa è una bella prima risposta :)
DJMcMayhem

1

Julia , 70 byte

f(x)=map(n->binomial(n-1,ceil(Int,x/2-(n^2-n)/4-1)),round(Int,√(x*2)))

1-based

Spiegazione:

trova prima il numero di riga, quindi il numero di colonna, quindi calcola il binomio


Benvenuti in PPCG!
Martin Ender,

sì grazie faccia felice
Jimmy Chen,


0

Pyth, 15 byte

@u+GSm.cHdhHhQY

0-indicizzato

Provalo

Spiegazione

@u+GSm.cHdhHhQY
 u          hQY   Reduce on [0, ..., input], starting with the empty list...
  +G              ... append to the accumulator...
    Sm.cHdhH      ... the sorted binomial coefficients.
@              Q  Take the 0-indexed element.


0

Rubino , 56 byte

->n{a=0;n-=a until n<a+=1;[*2..a].combination(n/2).size}

0-based

Prendi prima la riga e la colonna nel triangolo, quindi calcola il coefficiente binomiale corrispondente a quella posizione.

Provalo online!


0

In realtà , 8 byte

In gran parte basato sulla risposta Jelly di Jonathan Allan . Utilizza l'indicizzazione 0.

;r♂╣♂SΣE

Provalo online!

Ungolfing

          Implicit input n.
;         Duplicate n.
 r        Lowered range. [0..n-1].
  ♂╣      Pascal's triangle row of every number.
    ♂S    Sort every row.
      Σ   Sum each row into one array.
       E  Get the n-th element of the array (0-indexed).
          Implicit return.

Dovrebbe produrre un singolo numero; il nth della serie. Questo produce un array.
ricorsivo il

Ops. Fisso. Grazie @recursive
Sherlock9



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.