Rombo de Pascal

20

El rombo de Pascal (que en realidad es un triángulo) se obtiene agregando el patrón:

  *
 ***
  x

en lugar de

* *
 x

Esto significa que cada celda es la suma de las tres celdas en la fila directamente encima de ella y una celda en la fila 2 arriba. Al igual que el triángulo de Pascal, la fila cero tiene una sola 1que genera el triángulo.

Aquí están las primeras dos filas del rombo de Pascal

      1
    1 1 1
  1 2 4 2 1
1 3 8 9 8 3 1

Tarea

Dado un número de fila (comenzando desde la parte superior) y un número de columna (comenzando desde el primer elemento distinto de cero en esa fila), se genera el valor en esa celda en particular. Ambas entradas pueden estar indexadas en 1 o 0 (puede mezclar y combinar si lo desea).

Este es el por lo que debe intentar que el tamaño del archivo de su código fuente sea lo más pequeño posible.

OEIS A059317

Asistente de trigo
fuente
44
Al igual que con el triángulo de Pascal, la paridad del rombo crea patrones agradables y fractales .
Martin Ender
debe intentar que el tamaño del archivo de su código fuente sea lo más pequeño posible, ¿qué pasa si pongo mi código como argumento de línea de comandos? : P
Erik the Outgolfer
Busqué en Google los atajos y aparentemente arxiv.org/abs/1504.04404 dice que calcular el resultado directamente es inutilizable para el golf de código.
JollyJoker

Respuestas:

12

Haskell , 59 55 bytes

¿El rombo de Pascal? ¡Más como el rombo de Haskell! amiright?

4 bytes guardados gracias a Ørjan Johansen

Pensé en probar mi propio problema y practicar mi Haskell. Esperemos que esto inspire a más personas a responder esto.

1!1=1
n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1]

Pruébalo en línea!

Explicación

Esto está un poco desactualizado con el último golf

En lugar de calcular

  *
 ***
  x

Calculamos

*
***
  x

Esto inclina todo nuestro triángulo para convertirse

1
1 1 1
1 2 4 2 1
1 3 8 9 8 3 1

Esto alinea todas nuestras filas haciendo que sea más fácil indexar el enésimo elemento de cualquier columna. Luego definimos nuestros casos base.

La fila cero es todo ceros, así que

0!_=0

Hay un solo 1en la posición, 1,1así que definimos que

1!1=1

Y también definimos el resto de la primera fila como ceros

1!_=0

Luego definimos el caso general de forma recursiva utilizando el patrón descrito anteriormente:

n!k=(n-2)!(k-2)+(sum$map((n-1)!)[k-2..k])
Asistente de trigo
fuente
¡Golpéame! Esto también es mucho más limpio que el mío.
Julian Wolf
@JulianWolf Lo siento, cuando publiqué esto parecía que nadie más que Jorg estaba haciendo el problema. Todavía me gustaría ver tu solución.
Wheat Wizard
1
Puede guardar cuatro bytes con n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1].
Ørjan Johansen
10

Pascal , 122 bytes

Bueno, es el rombo de Pascal .

37 bytes guardados gracias a @manatwork

function f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;

Pruébalo en línea!

Uriel
fuente
Los paréntesis alrededor de toda la ifcondición no tienen sentido. (El 1º ifguarda 2 caracteres, en el 2º if1 carácter al no dejar espacio entre la thenpalabra clave y el dígito anterior). Ah, y la variable r es completamente innecesaria.
manatwork
Animal extraño que Pascal en Ideone. Nunca he visto comillas dobles delimitadas en ninguna variante de Pascal antes. Una cosa más se puede quitar: el ;antes de que los function's end.
manatwork
@manatwork sí, ahora cuando lo mencionaste, todos los demás editores en línea se quejaron al respecto
Uriel
@manatwork No estoy seguro de haber entendido. ¿no alargaría el código con el >= <=? Todavía necesito preservar elif n=0
Uriel
Lo siento @Uriel, ya no tengo esa versión. Actualmente estoy enfunction f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;
manatwork
7

PHP , 86 bytes

de forma recursiva solo la función fila y columna 0-indexada

function f($r,$c){return$r|$c?$r<0?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

Pruébalo en línea!

PHP , 114 bytes

forma recursiva programa completo fila y columna 0-indexado

<?=f(...$_GET);function f($r,$c){return$r|$c?$r<0|$c<0|$c>2*$r?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

Pruébalo en línea!

PHP , 129 bytes

fila y columna 0-indexada

for(;$r<=$argv[1];$l=$t[+$r++])for($c=~0;$c++<$r*2;)$t[+$r][$c]=$r|$c?$t[$r-2][$c-2]+$l[$c]+$l[$c-1]+$l[$c-2]:1;echo$l[$argv[2]];

Pruébalo en línea!

Jörg Hülsermann
fuente
y +1 por mejorarlo realmente :)
Uriel
4

Jalea , 22 20 19 bytes

3ḶṚp@Ḣḣ4
Ḟ_ЀÇ߀ȯ¬S

Toma un par de índice basado en 0 como argumento de línea de comandos.

Pruébalo en línea!

Dennis
fuente
3

MATL , 22 20 19 bytes

Ti:"2Y6Y+FT_Y)]!i_)

Ambas entradas están basadas en 0.

Pruébalo en línea!

Explicación

Deje ry cdenote las dos entradas, especificando fila y columna basadas en 0 respectivamente.

Cada nueva fila en el rombo de Pascal se puede construir a partir de la matriz que contiene las dos filas anteriores convolucionando con el núcleo [1 1 1; 0 1 0]y manteniendo intercambiadas las últimas dos filas del resultado. Esto se hace rveces, comenzando desde la matriz 1.

Resulta que es más corto usar el núcleo [0 1 0; 1 1 1; 0 1 0], que es un literal predefinido. Esto produce una fila adicional, que se descartará.

Considere, por ejemplo r = 3, que hay 3iteraciones.

  1. Empezando desde

    1
    

    convolución con [0 1 0; 1 1 1; 0 1 0]da

    0 1 0
    1 1 1
    0 1 0
    

    Mantener las dos últimas filas (la matriz completa, en este caso) e intercambiarlas da

    0 1 0
    1 1 1
    
  2. Convolución de lo anterior con [0 1 0; 1 1 1; 0 1 0]da

    0 0 1 0 0
    0 1 1 1 0
    1 2 4 2 1
    0 1 1 1 0
    

    La matriz formada por las dos últimas filas intercambiadas es

    0 1 1 1 0
    1 2 4 2 1
    

    Contiene la nueva fila en la parte inferior y la anterior extendida con ceros.

  3. Convolucionar nuevamente produce

    0 0 1 1 1 0 0
    0 1 2 3 2 1 0
    1 3 8 9 8 3 1
    0 1 2 4 2 1 0
    

    Tomar las dos últimas filas intercambiadas da

    0 1 2 4 2 1 0
    1 3 8 9 8 3 1
    

Una vez que rse han realizado las iteraciones, la salida está contenida en la última fila de la matriz final. Por ejemplo, para c = 2(basado en 0) el resultado sería 8. En lugar de indexar la última fila y la columna deseada, se puede utilizar un truco que explota la simetría de cada fila: la matriz final se transpone

0 1
1 3
2 8
4 9
2 8
1 3
0 1

y -cse toma su enésimo elemento. Esto utiliza la indexación lineal, es decir, la matriz se indexa mediante un único índice en el orden de columnas principales . Como la indexación es modular , la 0entrada-es la esquina inferior derecha (valor 1) y la -2entrada -th está dos pasos arriba (valor 8).

T       % Push true
i       % Input row number
:"      % Do the following that many times
  2Y6   %   Push predefined literal [0 1 0; 1 1 1; 0 1 0]
  Y+    %   2D convolution, increasing size
  FT_   %   Push [0 -1]
  Y)    %   Matrix with rows 0 (last) and -1 (second-last), in that order
]       % End
!       % Transpose
i       % Input: colun number
_       % Negate
)       % Entry with that index. Implicitly display
Luis Mendo
fuente
2

Haskell , 74 bytes

0#0=1
n#m|m<=2*n&&m>=0=sum[(n-a)#(m-b)|(a,b)<-zip[2,1,1,1]$2:[0..2]]
n#m=0

Pruébalo en línea!

Llame con n # m, donde nestá la fila y mes la columna.

Julian Wolf
fuente
m<=2*n&&m>=0puede ser justo n>0.
Ørjan Johansen el
2

Mathematica, 56 bytes

If[#<1,Boole[##==0],Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]]&

Función pura que toma dos argumentos enteros (primera fila, segunda columna) y devuelve un entero. Funciona también para argumentos enteros negativos, regresando 0. Una estructura recursiva bastante sencilla: If[#<1,Boole[##==0],...]define el comportamiento del caso base para la fila 0 (y superior), mientras Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]implementa la definición recursiva.

Greg Martin
fuente
1

JavaScript (ES6), 68 bytes

f=(y,x)=>x<0|x>y+y?0:x>0&x<y+y?f(--y,x)+f(y,--x)+f(y,--x)+f(--y,x):1
Neil
fuente
1

Mathematica, 53 bytes

D[1/(1-x(1+y+y^2(1+x))),{x,#},{y,#2}]/#!/#2!/.x|y->0&

Usando la función generadora.

alephalpha
fuente
0

Python 3 , 82 84 bytes

Esta es una implementación recursiva con filas y columnas indexadas 1. (Técnicamente necesita un f=frente, alguien me avisa si debo cambiarlo a 84 bytes. Todavía es nuevo y no estoy 100% seguro de las reglas).

Esto usa la fórmula recursiva que se encuentra en la página OEIS , pero con la k's' desplazada hacia la izquierda para alinearse correctamente. Coincidentemente, sum(f(n-1,k-i)for i in(0,1,2))es del mismo tamaño que f(n-1,k)+f(n-1,k-1)+f(n-1,k-2). Toda la función es el and ortruco de Python , donde la primera condición verifica si k está dentro del triángulo y no en el límite, en cuyo caso se usa la fórmula recursiva. Si no lo es, la parte después de que orse devuelve, que comprueba si kestá adentro (1, 2*n-1), es decir, en el límite, regresando Truey False. k+1in(2,2*n)es un byte más corto que k in(1,2*n-1). Ajustar eso entre paréntesis y poner un +frente se convierte a entero, que es lo que se necesita.

f=lambda n,k:2*n-1>k>1and sum(f(n-1,k-i)for i in(0,1,2))+f(n-2,k-2)or+(k+1in(2,2*n))

Pruébalo en línea!

C McAvoy
fuente
Las funciones recursivas necesitan el f=.
Wheat Wizard
Si bien personalmente estoy en desacuerdo con él de acuerdo con este meta consenso algo oculto, puede generar en Truelugar de 1porque se comporta como 1python. Esto le permite eliminar el +(...)al final. Entiendo que si no quieres hacer esto, porque hará que la salida se vea un poco extraña, es una opción.
Wheat Wizard
@WheatWizard Wow, eso es muy interesante. Gracias por el consejo.
C McAvoy
0

Java (OpenJDK 8) , 87 bytes

int f(int r,int c){return c<0|2*r<c?0:0<c&c<2*r?f(--r,c)+f(r,--c)+f(r,--c)+f(--r,c):1;}

Pruébalo en línea!

Al principio, estaba contento con mi método iterativo de 160 bytes ... Hmmm ... olvidémoslo, ¿de acuerdo?

Olivier Grégoire
fuente
0

Python 3 , 75 bytes

Esta es una lambda recursiva que toma la columna y la fila como enteros indexados a 0.

p=lambda r,c:(r<0 or((c==0)|p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

Aquí hay una versión (ligeramente) más legible con una función de impresión:

p = lambda r,c:(r<0 or ((c==0) | p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

def pp(r):
    ml = len(str(p(r,r)))+1
    for i in range(0, r):
            a=" "*ml*(r-i)
            for j in range(0,i*2 + 1):
                    a+=str(p(i,j))+(" "*(ml-len(str(p(i,j)))))
            print(a)
Eric Canam
fuente