Triángulo de Pascal (tipo de)

24

La mayoría de los que están aquí están familiarizados con el Triángulo de Pascal. Está formado por filas sucesivas, donde cada elemento es la suma de sus dos vecinos superior izquierdo y superior derecho. Aquí están las primeras 5filas (tomadas del triángulo Generate Pascal ):

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

Contraer estas filas a la izquierda

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

Ordenarlos en orden ascendente

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

Lee este triángulo por filas

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

Dada una entrada n, genera el nnúmero th en esta serie. Esto es OEIS 107430 .

Reglas

  • Puede elegir indexación basada en 0 o en 1. Indique cuál en su envío.
  • Se puede suponer que la entrada y la salida encajan en el tipo entero nativo de su idioma.
  • La entrada y salida se pueden dar por cualquier método conveniente .
  • Un programa completo o una función son aceptables. Si es una función, puede devolver el resultado en lugar de imprimirlo.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).
AdmBorkBork
fuente
66
Muy buen título!
Luis Mendo
1
Según el enlace OEIS, el único cambio requerido para generar esta secuencia en lugar de un coeficiente binomial es una división entera. Eso ciertamente cae bajo "trivial".
Peter Taylor
55
@PeterTaylor Esto no me parece un engaño obvio. Hay muchos otros enfoques posibles que pueden conducir a interesantes oportunidades de golf, especialmente para los idiomas que no tienen un binomio incorporado.
Arnauld
44
@PeterTaylor No estoy convencido de que esto sea un duplicado, tampoco. Hasta ahora, las respuestas de MATL, JavaScript y Pascal son bastante diferentes entre los dos desafíos. Sin embargo, dado que mi voto está abierto, aún no votaré.
AdmBorkBork
44
Totalmente de acuerdo con @AdmBorkBork. Así que cuéntame como volver a abrir el voto. Eso hace 3 ahora. ¿Cuántos votos se requieren para reabrir?
Luis Mendo

Respuestas:

9

JavaScript (ES6), 79 bytes

0 indexado.

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

Manifestación

¿Cómo?

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

Este algoritmo genera directamente las filas ordenadas del Triángulo de Pascal. Actualiza n de acuerdo con la longitud de la fila anterior hasta que exista un [n] . Por ejemplo, se requieren 6 iteraciones para 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 ]
                        ^^
Arnauld
fuente
Buen trabajo. Sin embargo, no estoy seguro si entiendo exactamente cómo funciona. Mi intento resultó ser mucho más largo que el tuyo.
kamoroso94
@ kamoroso94 He agregado una explicación.
Arnauld
¡Me encanta esto! Realmente disfruté averiguar lo que estaba haciendo.
Shaggy
6

Octava , 46 bytes

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

Basado en 1.

Pruébalo en línea!

Explicación

Considere n=4como un ejemplo.

pascal(n) da una matriz de Pascal:

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

Las filas del triángulo de Pascal son las antidiagoniales de esta matriz. Entonces se voltea verticalmente usandoflip(···)

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

que transforma las antidiagonales en diagonales.

spdiags(···) extrae las diagonales (distintas de cero), comenzando desde la parte inferior izquierda, y las organiza como columnas rellenas con ceros:

 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(···)ordena cada columna de esta matriz y asigna el resultado a la variable 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

La indexación lógica (···)(~~M)ahora se usa para extraer los nonzeros de esta matriz en orden de columna mayor (abajo, luego a través). El resultado es un vector de columna:

 1
 1
 1
 1
···
10
10
20

Finalmente, la nentrada enésima de este vector se extrae usando (···)(n), lo que en este caso da 1.

Luis Mendo
fuente
5

Python 2 , 86 78 72 bytes

-8 bytes gracias 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])))

Pruébalo en línea!

Sin golf

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)

Pruébalo en línea!

La función calcula recursivamente la fila del Triángulo de Pascal. Dada la fila actual como row, map(sum, zip([0] + row, row + [0])).
En cada llamada nse reduce la longitud de la fila actual. Si la función llega a la fila derecha, se nthdebe devolver el número más bajo de la fila.
Como la primera mitad de una fila está en orden ascendente y cada fila es simétrica, el número está en el índice n/2( índice 0, división entera).

ovs
fuente
4

Wolfram Language (Mathematica) , 55 bytes

La indexación está basada en 1.

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

Pruébalo en línea!

Explicación

Es probable que esto sea golfable, no soy un usuario muy experimentado de Mathematica.

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

Para cada n ∈ [0, Entrada] ∩ ℤ , genere la tabla de binomios con cada k ∈ [0, n] ∩ ℤ .

Sort/@

Ordenar cada uno. Utiliza una taquigrafía para Map[function,object]- function/@object.

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

Acoplar la lista resultante y recuperar el elemento cuyo índice en la lista es la entrada.

Sr. Xcoder
fuente
3

R , 58 bytes

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

Pruébalo en línea!

Calcula n choose kpara cada n,ken [0,1,...,n]como una matriz, las filas se ordenan en orden ascendente (*), y elimina los ceros, a continuación, selecciona el nelemento XX.

(*) Esto también los transforma en columnas, pero eso es mejor ya que R almacena una matriz como un vector en columnas, lo que nos permite indexar directamente en ella mientras se preserva el orden.

Giuseppe
fuente
3

Haskell , 143 132 125 123 bytes

((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 primera línea es una función sin puntos que toma un índice (basado en 0) y devuelve el número apropiado en la secuencia. Pruébalo en línea!

¡Este es mi primer programa Haskell! Estoy seguro de que puede acortarse mucho más. Los consejos son apreciados.

Guardado 2 bytes gracias a nimi

Sin golf

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
DLosc
fuente
Todavía tienes ien la función s, que se cambió el nombre a !, supongo. Si utiliza una función infija puedes colocar el ()torno reverse b: s(a,b)=reverse b!a.
nimi
@nimi Ah, gracias. Lo cambié en TIO pero perdí un lugar en el código aquí. Y gracias por el consejo de paréntesis.
DLosc
3

JavaScript, 57 bytes

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 indexado.

¿Cómo viene esto?

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

Este código es fácil de entender:

  • ccalcula la función de uso combinado: C (n, k) = C (n-1, k) + C (n-1, k-1); o 1 si k == 0 o k == n
  • función de ftratar de averiguar el número de fila y el índice de la fila, y luego llamar a la función C para obtener el resultado.

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

En este paso, tratamos de modificar la llamada a la función cpara c(i,r)que sea igual que el parámetro de f.

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

Probamos i<rsi está usando la función fo la función c. Es por eso que mantenemos almizcle i<rdurante la repetición de la función c.

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

En este paso, fusionamos estas dos funciones en una sola.

Después de un poco más de golf, finalmente obtuvimos la respuesta descrita anteriormente.

tsh
fuente
2

Jalea , 13 bytes

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

Pruébalo en línea!

Usando el algoritmo Dyalog de Uriel.

1 indexado.

Explicación:

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
Erik el Outgolfer
fuente
¿Podría agregar una explicación? No puedo entender qué þestá haciendo aquí.
Shaggy
1
@Shaggy Es un producto externo, agregaré una explicación.
Erik the Outgolfer
2

JavaScript (Node.js) , 65 bytes

Ni siquiera se usa una matriz. 0 indexado.

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)

Pruébalo en línea!

Explicación:

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
Shieru Asakoto
fuente
1

Pascal , 373 bytes

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 Es la función.

Pruébalo en línea!

Uriel
fuente
n=1 thenpuede ser n=1then.
Jonathan Frech
De manera similar, parece que if(k=0)thenpuede convertirse if k=0then.
Shaggy
si algún número siempre es mayor que 0, debe usarlo en wordlugar de integer.
tsh
1

Java 8, 187 bytes

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

Explicación:

Pruébalo en línea.

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);}
Kevin Cruijssen
fuente
1

MATL , 11 bytes

:qt!XnSXzG)

Basado en 1.

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

Considerar entrada 4 como un ejemplo. ;es el separador de fila para matrices o vectores de columna.

:     % 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
Luis Mendo
fuente
1

Lote, 128 bytes

@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 indexado.

Neil
fuente
¿Puedes agregar una explicación, por favor? No puedo seguir la lógica aquí.
AdmBorkBork
@AdmBorkBork Las primeras tres líneas calculan la fila ry la columna %1-(s-2)del %1th de la serie. La cuarta línea usa eso para calcular el coeficiente binomial (n k) = n!/(n-k)!k!= n(n-1)...(n+1-k)/(1)(2)...k= (n/1)((n-1)/2)...((n+1-k)/k). ¿Dónde está MathJax cuando lo necesito?
Neil
1

APL (Dyalog Classic) , 17 bytes

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

Pruébalo en línea!

Indexación basada en 0

tenga en cuenta que (49!98) > 2*53, es decir, el coeficiente binomial 98 sobre 49 es mayor que 2 53 , por lo que en ese punto Dyalog ya ha comenzado a perder precisión debido al punto flotante IEEE

ngn
fuente
@Abigail ver aquí y aquí
ngn
1

05AB1E , 10 bytes

0 indexado

ÝεDÝc{}˜sè

Pruébalo en línea!

Explicación

Ý             # 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>
Emigna
fuente
1

Jalea , 11 bytes

Ḷc€`Ṣ€Fḟ0ị@

Pruébalo en línea!

Un enlace monádico que toma el índice y devuelve un entero: utiliza la indexación basada en 1.

¿Cómo?

Realiza el desafío más o menos tal como está escrito, solo con más de la derecha del triángulo de Pascal (ceros) que luego se tira ...

Ḷ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 --------------^
Jonathan Allan
fuente
1

Rojo , 206 bytes

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]

Basado en 1

Pruébalo en línea!

Explicación:

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
]
Galen Ivanov
fuente
1

Perl, 48 bytes

Incluye +1parap

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

Utiliza la indexación de base 0.

Ton Hospel
fuente
1

J, 46 41 bytes

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

0 indexado

Pruébalo en línea!

Notas:

  • <.2&!@,:^:_1da el número de fila relevante del triángulo de Pascal redondeando hacia abajo el inverso de y choose 2.
  • /:~@(i.!<:)@] calcula la fila y la ordena.
  • [-2!] da el índice en la fila.
Kyle Miller
fuente
Hola. Bienvenido al sitio! Esta es una buena primera respuesta :)
DJMcMayhem
1

Julia , 70 bytes

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

Basado en 1

Explicación:

primero encuentra el número de fila, luego el número de columna, luego calcula el binomio

Jimmy Chen
fuente
Bienvenido a PPCG!
Martin Ender
sí, gracias cara feliz
Jimmy Chen
0

Pyth, 15 bytes

@u+GSm.cHdhHhQY

0 indexado

Intentalo

Explicación

@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.

fuente
0

Limpio , 80 bytes

import StdEnv

\n=flatten[sort[prod[j+1..i]/prod[1..i-j]\\j<-[0..i]]\\i<-[0..]]!!n

Pruébalo en línea!

Como una función lambda.

Οurous
fuente
0

Ruby , 56 bytes

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

Basado en 0

Primero obtenga la fila y la columna en el triángulo, luego calcule el coeficiente binomial correspondiente a esa posición.

Pruébalo en línea!

GB
fuente
0

En realidad , 8 bytes

En gran parte basado en la respuesta de Jonathan Allan Jelly . Utiliza indexación 0.

;r♂╣♂SΣE

Pruébalo en línea!

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.
Sherlock9
fuente
Se supone que produce un solo número; El nth de la serie. Esto produce una matriz.
recursivo
Whoops Fijo. Gracias @recursive
Sherlock9
0

C (gcc) , 140 123 bytes

F(n){n=n?n*F(~-n):1;}f(n,j,k,c){for(c=j=0;j<n;j++)for(k=0;k<=j/2;k++)if(++c==n||j&1|k-j/2&&++c==n)return F(j)/F(k)/F(j-k);}

Pruébalo en línea!

Jonathan Frech
fuente
@ceilingcat Gracias.
Jonathan Frech