Le losange de Pascal

20

Le losange de Pascal (qui est en fait un triangle) est obtenu en ajoutant dans le motif:

  *
 ***
  x

au lieu de

* *
 x

Cela signifie que chaque cellule est la somme des trois cellules de la ligne directement au-dessus et d'une cellule de la ligne 2 au-dessus. Tout comme le triangle de Pascal, la ligne zéro contient un simple 1qui génère le triangle.

Voici les deux premières rangées du losange de Pascal

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

Tâche

Étant donné un numéro de ligne (à partir du haut) et un numéro de colonne (à partir du premier élément différent de zéro sur cette ligne), affichez la valeur à cette cellule particulière. Les deux entrées peuvent être indexées 1 ou 0 (vous pouvez mélanger et assortir si vous le souhaitez).

Il s'agit de , vous devez donc viser à réduire autant que possible la taille du fichier de votre code source.

OEIS A059317

Assistant de blé
la source
4
Comme pour le triangle de Pascal, la parité du losange crée de jolis motifs fractals .
Martin Ender
vous devriez viser à rendre la taille du fichier de votre code source aussi petite que possible et si je mets mon code en argument de ligne de commande? : P
Erik the Outgolfer
Je suis allé sur Google pour les raccourcis et apparemment arxiv.org/abs/1504.04404 dit que le calcul direct du résultat est inutilisable pour le golf de code.
JollyJoker

Réponses:

12

Haskell , 59 55 octets

Le losange de Pascal? Plus comme le losange d'Haskell! ai-je raison?

4 octets économisés grâce à Ørjan Johansen

Je pensais que je devrais essayer mon propre problème et pratiquer mon Haskell. Espérons que cela incitera plus de gens à répondre à cette question.

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

Essayez-le en ligne!

Explication

C'est un peu dépassé avec le dernier golf

Au lieu de calculer

  *
 ***
  x

Nous calculons

*
***
  x

Cela incline tout notre triangle pour devenir

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

Cela aligne toutes nos lignes, ce qui facilite l'indexation du nième élément de n'importe quelle colonne. Nous définissons ensuite nos cas de base.

La ligne zéro est entièrement composée de zéros.

0!_=0

Il y a un seul 1en position 1,1donc nous définissons que

1!1=1

Et nous définissons le reste de la première ligne comme des zéros

1!_=0

Ensuite, nous définissons récursivement le cas général en utilisant le modèle décrit ci-dessus:

n!k=(n-2)!(k-2)+(sum$map((n-1)!)[k-2..k])
Assistant de blé
la source
Battez-moi! C'est aussi beaucoup plus propre que le mien.
Julian Wolf
@JulianWolf Désolé à ce sujet, lorsque j'ai posté cela, il semblait que personne d'autre que Jorg ne faisait le problème. J'aimerais toujours voir votre solution.
Wheat Wizard
1
Vous pouvez enregistrer quatre octets avec n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1].
Ørjan Johansen
10

Pascal , 122 octets

Eh bien, c'est le losange de Pascal .

37 octets économisés grâce à @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;

Essayez-le en ligne!

Uriel
la source
Les parenthèses autour de la ifcondition entière sont inutiles. (Le 1er, ifvous enregistrez 2 caractères, sur le 2ème if1 en ne laissant aucun espace entre le thenmot-clé et le chiffre précédent.) Oh, et la variable r est complètement inutile.
manatwork
Animal bizarre que Pascal sur Ideone. Jamais vu des guillemets délimités par des guillemets doubles dans une variante Pascal auparavant. Une chose que vous pouvez supprimer: l' ;avant les function« s end.
manatwork
@manatwork oui, maintenant quand vous l'avez mentionné, tous les autres éditeurs en ligne s'en sont plaints
Uriel
@manatwork Je ne suis pas sûr d'avoir compris. ne serait-ce pas simplement allonger le code avec le >= <=? J'ai encore besoin de préserver leif n=0
Uriel
Désolé @Uriel, je n'ai plus cette version. Actuellement je suisfunction 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 octets

manière récursive uniquement la ligne de fonction et la colonne 0-indexé

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

Essayez-le en ligne!

PHP , 114 octets

manière récursive ligne et colonne de programme complet indexées 0

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

Essayez-le en ligne!

PHP , 129 octets

ligne et colonne indexées 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]];

Essayez-le en ligne!

Jörg Hülsermann
la source
et +1 pour l'avoir réellement amélioré :)
Uriel
4

Gelée , 22 20 19 octets

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

Prend une paire d'index basée sur 0 comme argument de ligne de commande.

Essayez-le en ligne!

Dennis
la source
3

MATL , 22 20 19 octets

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

Les deux entrées sont basées sur 0.

Essayez-le en ligne!

Explication

Soit ret cdénotons les deux entrées, en spécifiant respectivement une ligne et une colonne basées sur 0.

Chaque nouvelle ligne du losange de Pascal peut être construite à partir de la matrice contenant les deux lignes précédentes en convoluant avec le noyau [1 1 1; 0 1 0]et en gardant les deux dernières lignes du résultat échangées. Cela se fait plusieurs rfois, à partir de la matrice 1.

Il s'avère plus court d'utiliser le noyau [0 1 0; 1 1 1; 0 1 0], qui est un littéral prédéfini. Cela produit une ligne supplémentaire, qui sera supprimée.

Considérez par exemple r = 3, donc il y a des 3itérations.

  1. A partir de

    1
    

    convolution avec [0 1 0; 1 1 1; 0 1 0]donne

    0 1 0
    1 1 1
    0 1 0
    

    Garder les deux dernières lignes (la matrice entière, dans ce cas) et les échanger donne

    0 1 0
    1 1 1
    
  2. Convolution de ce qui précède avec [0 1 0; 1 1 1; 0 1 0]donne

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

    La matrice formée par les deux dernières lignes permutées est

    0 1 1 1 0
    1 2 4 2 1
    

    Celui-ci contient la nouvelle ligne en bas et la précédente étendue avec des zéros.

  3. Convoluer à nouveau donne

    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
    

    Prendre les deux dernières lignes permutées donne

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

Une fois les ritérations effectuées, la sortie est contenue dans la dernière ligne de la matrice finale. Par exemple, pour c = 2(basé sur 0), le résultat serait 8. Au lieu d'indexer la dernière ligne et la colonne souhaitée, une astuce peut être utilisée qui exploite la symétrie de chaque ligne: la matrice finale est transposée

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

et son -c-ème élément est pris. Cela utilise une indexation linéaire, c'est-à-dire que la matrice est indexée par un index unique dans l'ordre des colonnes . Étant donné que l'indexation est modulaire , l' 0entrée est le coin inférieur droit (valeur 1) et l' -2entrée -th est deux étapes au-dessus (valeur 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
la source
2

Haskell , 74 octets

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

Essayez-le en ligne!

Appelez avec n # m, où nest la ligne et mla colonne.

Julian Wolf
la source
m<=2*n&&m>=0peut être juste n>0.
Ørjan Johansen
2

Mathematica, 56 octets

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

Fonction pure prenant deux arguments entiers (première ligne, deuxième colonne) et renvoyant un entier. Fonctionne également pour les arguments entiers négatifs, renvoyant 0. Une structure récursive assez simple: If[#<1,Boole[##==0],...]définit le comportement de cas de base pour la 0ème ligne (et au-dessus), tandis que Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]met en œuvre la définition récursive.

Greg Martin
la source
1

JavaScript (ES6), 68 octets

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
la source
1

Mathematica, 53 octets

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

Utilisation de la fonction de génération.

alephalpha
la source
0

Python 3 , 82 84 octets

Il s'agit d'une implémentation récursive avec des lignes et des colonnes indexées sur 1. (Techniquement, il a besoin d'un f=devant, quelqu'un m'a fait savoir si je devais le changer en 84 octets. Toujours nouveau et pas sûr à 100% des règles.)

Cela utilise la formule récursive trouvée sur la page OEIS , mais avec celle kdécalée vers la gauche pour s'aligner correctement. Par coïncidence, sum(f(n-1,k-i)for i in(0,1,2))est de la même taille que f(n-1,k)+f(n-1,k-1)+f(n-1,k-2). La fonction entière est l' and orastuce Python , où la première condition vérifie si k est à l'intérieur du triangle et non sur la frontière, auquel cas la formule récursive est utilisée. Si is n'est pas, la partie après le orest retournée, qui vérifie si kest dedans (1, 2*n-1), c'est-à-dire sur la frontière, en retournant Trueet False. k+1in(2,2*n)est un octet plus court que k in(1,2*n-1). Envelopper cela entre parenthèses et mettre un +devant convertit en entier, ce qui est nécessaire.

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

Essayez-le en ligne!

C McAvoy
la source
Les fonctions récursives ont besoin de f=.
Wheat Wizard
Bien que je sois personnellement en désaccord avec ce méta-consensus quelque peu enfoui, vous pouvez produire Trueau lieu de 1car il se comporte comme 1Python. Cela vous permet de supprimer le +(...)à la fin. Je comprends que si vous ne voulez pas faire cela, car cela rendra la sortie un peu étrange, c'est une option.
Wheat Wizard
@WheatWizard Wow, c'est très intéressant. Merci pour le conseil.
C McAvoy
0

Java (OpenJDK 8) , 87 octets

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

Essayez-le en ligne!

Au début, j'étais content de ma méthode itérative de 160 octets ... Hmmm ... oublions ça, OK?

Olivier Grégoire
la source
0

Python 3 , 75 octets

Il s'agit d'un lambda récursif qui prend la colonne et la ligne comme des entiers indexés 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

Voici une version (légèrement) plus lisible avec une fonction d'impression:

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
la source