Numéros de Motzkin


30

Le nième numéro de Motzkin est le nombre de chemins de (0, 0) à (n, 0) où chaque étape est de la forme (1, -1), (1, 0) ou (1, 1), et le chemin ne descend jamais en dessous de y = 0.

Voici une illustration de ces chemins pour n = 1, 2, 3, 4, à partir du lien ci-dessus:

Numéros de Motzkin

La séquence souhaitée est OEIS A001006 . OEIS a quelques autres caractérisations de la séquence.


Vous recevrez un entier positif n en entrée. Vous devez sortir le nième numéro Motzkin.

Voici les numéros de Motzkin 1 à 10:

1, 2, 4, 9, 21, 51, 127, 323, 835, 2188

Toutes les méthodes d'entrée et de sortie standard sont autorisées. Des échappatoires standard s'appliquent.

C'est le golf de code. Le moins d'octets gagne.


Quel est l'ensemble minimum de nombres Motzkin que nous devons être en mesure de générer?
Addison Crump


@FlagAsSpam Tous, jusqu'à des limites de temps / mémoire / type de données.
isaacg

Je pense que les langues ont besoin d'un mot Dyck intégré maintenant.
lirtosiast

Réponses:


15

MATL , 13 14 octets

i-2/t.5+hH4Zh

Exemple:

>> matl i-2/t.5+hH4Zh
> 6
51

EDIT (16 juin 2017): vous pouvez l' essayer en ligne! Notez également que dans les versions modernes de la langue (postérieures à ce défi), le ipourrait être supprimé.

Explication

Assez simple, en utilisant l'équivalence (voir l'équation (10)) avec la fonction hypergéométrique :

entrez la description de l'image ici

De la définition de la fonction hypergéométrique

entrez la description de l'image ici

il est clair que l'ordre des deux premiers arguments peut être échangé, ce qui économise un octet.

i         % input                                                   
-2/       % divide by -2
t.5+      % duplicate and add 0.5
h         % horizontal concatenation into a vector                               
H         % number 2
4         % number literal                                          
Zh        % hypergeometric function with three inputs (first input is a vector)

1
Cette réponse est la plus courte et la plus ancienne d'environ une heure et demie, donc je l'accepte.
isaacg

Merci! Je pouvais à peine imaginer que MATL serait même lié à Pyth. C'est un langage tellement dur à battre, bon travail pour le concevoir!
Luis Mendo

11

Rétine , 59 58 octets

+`(\D*)1(1*)
:$1<$2:$1>$2:$1_$2:
:(_|()<|(?<-2>)>)+:(?!\2)

Prend entrée en unaire . L'entrée 7 (c'est-à-dire 1111111) prend un certain temps mais se termine toujours en moins d'une minute. Je n'irais pas beaucoup plus loin que ça.

Essayez-le en ligne.

Explication

Une caractérisation différente des nombres Motzkin est le nombre de chaînes de trois caractères différents, où deux d'entre eux sont correctement équilibrés (d'où la relation étroite avec les nombres catalans, qui sont les mêmes sans le troisième caractère indépendant de l'équilibrage).

Les groupes d' équilibrage de .NET sont très bonnes à détecter les chaînes correctement adaptées, de sorte que nous générons simplement toutes les chaînes de longueur N( à l' aide _, <et >que les trois caractères) et on compte le nombre de ceux -ci sont correctement équilibrés. Par exemple pour N = 4les chaînes valides sont:

____
__<>
_<_>
_<>_
<__>
<_>_
<>__
<<>>
<><>

Par rapport à la définition du défi, _correspond à une (1,0)étape, <vers (1,1)et >vers (1,-1).

Quant au code réel, le :est utilisé comme séparateur entre les différentes chaînes. La deuxième expression régulière n'est qu'une forme golfique de l'expression régulière .NET standard pour les chaînes équilibrées .

Quelque chose à noter est qu'il n'y a qu'un seul :inséré entre les chaînes à chaque étape, mais le deuxième regex correspond à une première et à une fin :(et puisque les correspondances ne peuvent pas se chevaucher, cela signifie que les chaînes adjacentes générées à partir d'un modèle à la dernière étape ne peuvent pas correspondre à la fois ). Cependant, ce n'est pas un problème, car tout au plus l'un de ces trois peut jamais correspondre:

  • Si la chaîne se terminant par _correspond, le préfixe sans celui-ci _est déjà correctement équilibré et / <ou >annulerait cet équilibre.
  • Si la chaîne se terminant par des >correspondances, la chaîne est équilibrée avec celle-ci >, alors _ou <annulerait cet équilibre.
  • Les cordes se terminant par <ne peuvent jamais être équilibrées.

Il est dommage que «\» ait une signification particulière, sinon l'utilisation des caractères «_ / \» conviendrait mieux à l'esprit de la question.
Neil

9

Python 2, 51 octets

M=lambda n:n<1or sum(M(k)*M(n-2-k)for k in range(n))

Utilise la formule de Mathworld

entrez la description de l'image ici

Enregistre les caractères en mettant le M[n-1]terme dans la somme comme k=n-1, ce qui donne M[-1]*M[n-1], avec M[-1]=1comme partie de la condition initiale.

Edit: Un caractère plus court écrit la somme récursivement:

M=lambda n,k=0:n<1or k<n and M(k)*M(n-2-k)+M(n,k+1)

D'autres approches qui se sont révélées plus longues:

M=lambda n,i=0:n and(i>0)*M(n-1,i-1)+M(n-1,i)+M(n-1,i+1)or i==0
M=lambda n:+(n<2)or(3*~-n*M(n-2)+(n-~n)*M(n-1))/(n+2)

8

Pyth, 15 octets

Ls*V+KyMb1+t_K1

Cela définit une fonction y. Essayez-le en ligne: Démonstration

Explication:

Soit y[n]le n-ième nombre de Motzkin. Je calcule y[n]avec la formule

y[n] = dot product of (y[0], ..., y[n-1], 1) and (y[n-2], ..., y[0], 1)

Notez que le premier vecteur est plus grand que le second (sauf lors du calcul y[0]). Dans ce cas, Pyth ignore automatiquement le 1 à la fin du premier vecteur, de sorte que les deux vecteurs sont de longueur égale.

Ls*V+KyMb1+t_K1
L                 define a function y(b), which returns:
      yMb            compute the list [y[0], y[1], ..., y[b-1]]
     K               assign it to K
  *V                 vectorized multiplication of
    +K   1             * K with a 1 at the end
          +t_K1        * reverse(K), remove the first element, and append 1
 s                   return the sum (dot product)

Cette formule est une variante de l'une des formules répertoriées sur OEIS. C'est peut-être un peu stupide. En raison du 1 à la fin du premier vecteur (qui rend les longueurs inégales), je n'ai pas vraiment à donner à la récursivité un cas de base. Et j'avais l'espoir que les deux +...1puissent être joués d'une manière ou d'une autre. Il s'avère que je ne peux pas.

Vous pouvez définir une récursivité similaire avec un produit scalaire de vecteurs de longueur égale et définir le cas de base y[0] = 1avec le même nombre d'octets.


8

CJam (20 octets)

.5X]{__W%.*:++}qi*W=

Démo en ligne

Comme Mego l'a noté dans les commentaires sur la question, cela est très étroitement lié aux nombres catalans: changez le .5en 1et compensez l'index par un (ou supprimez simplement .5entièrement et laissez l'index inchangé) pour obtenir des nombres catalans.

La récurrence utilisée est

a (n + 2) - a (n + 1) = a (0) * a (n) + a (1) * a (n-1) + ... + a (n) * a (0). [Bernhart]

à partir de la page OEIS. La récurrence correspondante pour les nombres catalans est répertoriée comme

a (n) = Sum_ {k = 0..n-1} a (k) a (n-1-k).


6

Sérieusement, 21 octets

,;╗r`;τ╜█@;u@τ╣║\*`MΣ

Emprunte du code de la solution de numéros catalans de Quintopia , en particulier l'amélioration que j'ai apportée dans les commentaires.

J'utilise la formule suivante:

formule motzkin

Puisque nCkest 0 pour k > n, je fais la somme jusqu'à n-1, car ces valeurs seront toutes égales à 0 et n'affecteront donc pas la somme.

Essayez-le en ligne

Explication:

,;╗r`;τ╜█@;u@τ╣║\*`MΣ
,;╗                    push input, dupe, store one copy in register 0
   r                   push range(0, n) ([0,n-1])
    `             `M   map the function:
     ;τ╜█@               dupe k, push C(n, 2*k), swap with k
          ;u@τ╣║\        push the kth Catalan number
                 *       multiply
                    Σ  sum

C(n, 2*k)fait quoi maintenant?
Addison Crump

@FlagAsSpam C(n,k) = nCk, ou le nombre de combinaisons d' kéléments d'un pool d' néléments.
Mego

Oh, cela a plus de sens que ce que je pensais. +1.
Addison Crump

@FlagAsSpam Je ne pense pas que je veux savoir ce que vous pensiez que c'était ...
Mego

5

R, 64 octets

f=function(n)ifelse(n<2,1,f(n-1)+sum(rev(s<-sapply(2:n-2,f))*s))

Utilise également la formule Mathworld de la réponse python @ xnor . Merci aux règles de priorité, 2:n-2est équivalent à 0:(n-2).

Cas de test:

> f(0)
[1] 1
> f(1)
[1] 1
> f(5)
[1] 21
> f(10)
[1] 2188
> sapply(0:20,f)
 [1]        1        1        2        4        9       21       51      127
 [9]      323      835     2188     5798    15511    41835   113634   310572
[17]   853467  2356779  6536382 18199284 50852019

5

Mathematica, 31 30 octets

AppellF1[-#/2,.5,-#/2,2,4,4]&

Pour le plaisir, voici une version de 37 octets

Hypergeometric2F1[(1-#)/2,-#/2,2,4]&

et version 52 octets

SeriesCoefficient[1-x-Sqrt[1-2x-3x^2],{x,0,#+2}]/2&

4

Gelée , 17 14 13 octets

×US;
1;HÇƓ¡1ị

Cela utilise la relation de récurrence de la réponse de @ PeterTaylor . Essayez-le en ligne!

Comment ça marche

×US;      Define a helper link. Left argument: a (list)

×U        Multiply (×) a by its reverse (U).
  S       Compute the sum of the resulting list.
   ;      Prepend it to a.
          Return the result.

1;HÇƓ¡1ị  Define the main link.

1         Set the left argument to 1.
 ;H       Append the half of 1 to 1. Result: [1, 0.5].
    Ɠ     Read an integer n from STDIN.
   Ç ¡    Call the helper link (Ç) n times.
      1ị  Retrieve the result at index 1.

2

Mathematica, 44 42 34 octets

Sum[#!/(i!(i+1)!(#-2i)!),{i,0,#}]&

Une version 35 octets:

Coefficient[(1+x+1/x)^#,x]/#&[#+1]&

2

Pari / GP , 38 36 26 octets

n->(1+x+x^2)^n++/n\x^n++%x

Essayez-le en ligne!

En utilisant l'équation (11) de MathWorld :

Mn=1n+1(n+11)2

où est un coefficient trinomial . Par définition, est le coefficient de dans l'expansion de . ( n(nk)2xn+k(1+x+x2)n(nk)2xn+k(1+x+x2)n


A 14 octets Samau fonction en utilisant la première définition du coefficient trinôme: );;7 2D$ⁿ$)╡$÷. Je ne le posterai pas comme réponse car la langue est plus récente que la question.
alephalpha

L'afficher est très bien, il vous suffit d'ajouter un avertissement que la soumission n'est pas admissible à gagner parce que, comme vous l'avez dit, la langue est plus récente que la question.
Alex A.

2

05AB1E , 13 12 octets

ÝI<ãʒ.øDŸQ}g

Essayez-le en ligne!

Bien que la plupart des réponses utilisent une formule ou une relation de récurrence, il s'agit d'une approche de comptage simple.

Chaque chemin possible à travers la grille est représenté par la liste de ses coordonnées y. Pour n segments, il y a un total de (n + 1) points, mais le premier et le dernier sont nécessairement 0, ce qui laisse (n-1) points à spécifier.

Ý           # range [0..n]
 I<         # n - 1
   ã        # cartesian power

Nous avons maintenant une liste de chemins (n'incluant pas encore le 0 initial et le 0 final). Par construction, aucun d'entre eux ne descend jamais en dessous de 0. Cependant, certains d'entre eux ont des pentes illégales (par exemple sauter de 0 à 2), nous devons donc les filtrer.

ʒ      }g   # count how many paths satistfy the following condition
 0.ø        # surround with 0
      Q     # is equal to
    DŸ      # its own fluctuating range

Ÿest la plage de fluctuation intégrée. S'il y a une paire de nombres non adjacents, elle remplira les nombres manquants (par exemple [0, 2] devient [0, 1, 2]). Seuls les chemins légaux resteront inchangés.

Une façon peut-être plus intuitive de vérifier les pentes illégales serait üαà(affirmer que le maximum de différences absolues par paire est égal à 1). Cependant, cela manque le chemin plat [0, 0, ... 0], qui coûte un octet supplémentaire à corriger.

Enfin, notez que le code réel utilise où cette explication utilise 0.ø. Au lieu d'entourer le chemin avec 0, cela entoure l'entrée implicite avec deux copies du chemin. Cela met le système de coordonnées à l'envers et à l'envers, mais est par ailleurs équivalent.


2

Stax , 12 octets

îu¬@Y≤ÅÉÑ(πε

Exécuter et déboguer

Je ne sais pas comment faire une composition mathématique sophistiquée, mais cela repose essentiellement sur une construction de programmation dynamique

M(0) = 1
M(1) = 1
M(n + 1) = M(n) + sum(M(k) * M(n - k - 1) for k in [0..n-1])

1

Rubis, 50

mise en œuvre simple de la relation de récurrence.

g=->n{n<2?1:(3*(n-1)*g[n-2]+(2*n+1)*g[n-1])/(n+2)}

1

Brain-Flak , 90 octets

(([{}]<(())>)<{({}()<{<>([({})]({}[({})]({}<>{}<>)))<>}<>>)}>){({}()<{}>)}{}({}{}[{}{}]<>)

Essayez-le en ligne!

Calcule , où est un coefficient trinomial . Je n'ai pu trouver cette formule nulle part, donc je ne peux pas la référencer, mais elle peut être prouvée de la même manière que la formule analogue .(n0)2(n2)2(nk)2Cn=(2nCn=(2nn)(2nn+1)


0

ES6, 44 octets

f=(n,k=0)=>n<1?1:k<n&&f(k)*f(n-2-k)+f(n,k+1)

Port simple de la solution récursive Python @ xnor. Besoin n<1?1:car n<1||ferait f(0)retour true.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.