Rombo di Pascal


20

Il rombo di Pascal (che in realtà è un triangolo) si ottiene aggiungendo nel modello:

  *
 ***
  x

invece di

* *
 x

Ciò significa che ogni cella è la somma delle tre celle sulla riga direttamente sopra di essa e una cella sulla riga 2 sopra di essa. Proprio come il triangolo di Pascal, la riga di Zeroth ha un singolo 1su di essa che genera il triangolo.

Ecco le prime due file di rombo di Pascal

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

Compito

Dato un numero di riga (a partire dall'alto) e un numero di colonna (a partire dal primo elemento diverso da zero su quella riga) restituisce il valore in quella particolare cella. Entrambi gli input possono essere indicizzati 1 o 0 (è possibile combinare e abbinare se lo si desidera).

Questo è quindi dovresti mirare a ridurre al minimo le dimensioni del tuo codice sorgente.

OEIS A059317



dovresti mirare a ridurre al minimo le dimensioni del tuo codice sorgente e se inserissi il mio codice come argomento da riga di comando? : P
Erik the Outgolfer,

Sono andato su Google per le scorciatoie e apparentemente arxiv.org/abs/1504.04404 dice che il calcolo del risultato direttamente è inutilizzabile per il golf del codice.
JollyJoker,

Risposte:


12

Haskell , 59 55 byte

Pascal's Rhombus? Più come il rombo di Haskell! ho ragione?

4 byte salvati grazie a Ørjan Johansen

Ho pensato di provare il mio problema e praticare il mio Haskell. Spero che questo ispirerà più persone a rispondere a questo.

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

Provalo online!

Spiegazione

Questo è un po 'obsoleto con l'ultimo golf

Invece di calcolare

  *
 ***
  x

Calcoliamo

*
***
  x

Questo inclina il nostro intero triangolo per diventare

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

Questo allinea tutte le nostre righe facilitando l'indicizzazione dell'ennesimo elemento di qualsiasi colonna. Definiamo quindi i nostri casi di base.

La riga zeroth è quindi tutti zeri

0!_=0

C'è un singolo 1in posizione, 1,1quindi lo definiamo

1!1=1

E definiamo anche il resto della prima riga come zero

1!_=0

Quindi definiamo il caso generale in modo ricorsivo usando il modello sopra descritto:

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

Sconfiggimi! Anche questo è molto più pulito del mio.
Julian Wolf,

@JulianWolf Mi dispiace, quando l'ho postato sembrava che nessun altro a parte Jorg stesse facendo il problema. Mi piacerebbe ancora vedere la tua soluzione.
Wheat Wizard

1
È possibile salvare quattro byte con n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1] .
Ørjan Johansen,

10

Pascal , 122 byte

Bene, sono i rombo di Pascal .

37 byte salvati grazie 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;

Provalo online!


Le parentesi attorno all'intera ifcondizione sono inutili. (Il 1 ° ifsi salvano 2 caratteri, il 2 ° if1 carattere non lasciando spazio tra la thenparola chiave e la cifra precedente.) Oh, e la variabile r è completamente inutile.
arte

Strano animale che Pascal su Ideone. Non ho mai visto stringhe doppie delimitate da virgolette in nessuna variante Pascal prima. Una cosa di più potete rimuovere: la ;prima che la function's end.
arte

@manatwork sì, ora quando l'hai menzionato, tutti gli altri editor online si sono lamentati per questo
Uriel

@manatwork Non sono sicuro di aver capito. non allungherebbe il codice con il >= <=? Devo ancora preservareif n=0
Uriel il

Scusa @Uriel, non ho più quella versione. Attualmente sono afunction 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 byte

modo ricorsivo solo la funzione riga e colonna 0-indicizzata

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

Provalo online!

PHP , 114 byte

modo ricorsivo riga completa del programma e colonna 0-indicizzata

<?=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;}

Provalo online!

PHP , 129 byte

riga e colonna indicizzate 0

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

Provalo online!


e +1 per migliorarlo effettivamente :)
Uriel,


3

MATL , 22 20 19 byte

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

Entrambi gli ingressi sono basati su 0.

Provalo online!

Spiegazione

Let randc indicare i due input, specificando rispettivamente riga e colonna in base 0.

Ogni nuova riga nel rombo di Pascal può essere costruita dalla matrice contenente le due righe precedenti, contorcendosi con il kernel [1 1 1; 0 1 0]e mantenendo le ultime due righe del risultato scambiate. Questo viene fatto rvolte, a partire dalla matrice 1.

Risulta più breve usare il kernel [0 1 0; 1 1 1; 0 1 0] , che è un valore letterale predefinito. Questo produce una riga aggiuntiva, che verrà scartata.

Considera ad esempio r = 3, quindi ci sono 3iterazioni.

  1. A partire da

    1
    

    convoluzione con [0 1 0; 1 1 1; 0 1 0]

    0 1 0
    1 1 1
    0 1 0
    

    Mantenere le ultime due righe (l'intera matrice, in questo caso) e scambiarle dà

    0 1 0
    1 1 1
    
  2. Convoluzione di quanto sopra con [0 1 0; 1 1 1; 0 1 0]

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

    La matrice formata dalle ultime due righe scambiate è

    0 1 1 1 0
    1 2 4 2 1
    

    Questo contiene la nuova riga in basso e la precedente estesa con zeri.

  3. Convolgere di nuovo i rendimenti

    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
    

    Dare le ultime due righe scambiate

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

Dopo raver eseguito le iterazioni, l'output è contenuto nell'ultima riga della matrice finale. Ad esempio, per c = 2(basato su 0) il risultato sarebbe 8. Invece di indicizzare l'ultima riga e la colonna desiderata, può essere usato un trucco che sfrutta la simmetria di ogni riga: la matrice finale viene trasposta

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

e -cviene preso il suo elemento -th. Questo utilizza l'indicizzazione lineare, ovvero la matrice è indicizzata da un singolo indice in ordine di colonna maggiore . Poiché l'indicizzazione è modulare , 0-entry è l'angolo in basso a destra (valore 1) e la -2voce -th è due passaggi sopra (valore 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



2

Mathematica, 56 byte

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

Funzione pura che accetta due argomenti interi (riga prima, colonna seconda) e restituisce un numero intero. Funziona anche per argomenti interi negativi, di ritorno 0. Una struttura ricorsiva piuttosto semplice: If[#<1,Boole[##==0],...]definisce il comportamento del caso base per la 0a riga (e sopra), mentre Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]implementa la definizione ricorsiva.



1

JavaScript (ES6), 68 byte

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

1

Mathematica, 53 byte

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

Utilizzando la funzione di generazione.


0

Python 3 , 82 84 byte

Questa è un'implementazione ricorsiva con righe e colonne con 1 indice. (Tecnicamente ha bisogno di unf= fronte, qualcuno mi faccia sapere se dovrei cambiarlo a 84 byte. Ancora nuovo e non sicuro al 100% delle regole.)

Questo utilizza la formula ricorsiva presente nella pagina OEIS , ma con quella kspostata a sinistra per allinearsi correttamente. Per coincidenza, ha sum(f(n-1,k-i)for i in(0,1,2))le stesse dimensioni di f(n-1,k)+f(n-1,k-1)+f(n-1,k-2). L'intera funzione è il and ortrucco di Python , in cui la prima condizione controlla se k è all'interno del triangolo e non sul limite, nel qual caso viene utilizzata la formula ricorsiva. In caso contrario, la parte dopo la orrestituzione viene restituita, il che verifica se kè presente (1, 2*n-1), vale a dire sul confine, ritorno Truee False. k+1in(2,2*n)è un byte più breve di k in(1,2*n-1). Avvolgendolo tra parentesi e mettendo un +in primo piano si converte in numero intero, che è ciò che è necessario.

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

Provalo online!


Le funzioni ricorsive richiedono il f=.
Wheat Wizard il

Mentre io personalmente non sono d'accordo con esso in base al presente meta consensi un po 'sepolto, si può uscita Trueinvece di 1perché si comporta come 1al pitone. Questo ti permette di rimuovere il +(...)alla fine. Capisco se non vuoi farlo, perché renderà l'output un po 'strano, è un'opzione.
Wheat Wizard

@WheatWizard Wow, è molto interessante. Grazie per il consiglio.
C McAvoy,


0

Python 3 , 75 byte

Questo è un lambda ricorsivo che accetta colonna e riga come numeri interi con indice 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

Ecco una versione (leggermente) più leggibile con una funzione di stampa:

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