Numeri di Motzkin


30

L'ennesimo numero Motzkin è il numero di percorsi da (0, 0) a (n, 0) in cui ogni passaggio ha la forma (1, -1), (1, 0) o (1, 1) e il percorso non scende mai sotto y = 0.

Ecco un'illustrazione di questi percorsi per n = 1, 2, 3, 4, dal link sopra:

Numeri di Motzkin

La sequenza desiderata è OEIS A001006 . OEIS ha alcune altre caratterizzazioni della sequenza.


Ti verrà dato un numero intero positivo n come input. Dovresti produrre l'ennesimo numero Motzkin.

Ecco i numeri Motzkin da 1 a 10:

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

Sono consentiti tutti i metodi di input e output standard. Si applicano scappatoie standard .

Questo è il codice golf. Vince il minor numero di byte.


Qual è l'insieme minimo di numeri Motzkin che dobbiamo essere in grado di generare?
Addison Crump,


@FlagAsSpam Tutti, fino a limiti di tempo / memoria / tipo di dati.
isaacg,

Penso che le lingue abbiano bisogno di parole Dyck integrate adesso.
lirtosiast,

Risposte:


15

MATL , 13 14 byte

i-2/t.5+hH4Zh

Esempio:

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

EDIT (16 giugno 2017): puoi provarlo online! Si noti inoltre che nelle versioni moderne della lingua (che post-date questa sfida) ipotrebbero essere rimosse.

Spiegazione

Abbastanza semplice, usando l'equivalenza (vedi equazione (10)) con la funzione ipergeometrica :

inserisci qui la descrizione dell'immagine

Dalla definizione della funzione ipergeometrica

inserisci qui la descrizione dell'immagine

è chiaro che l'ordine dei primi due argomenti può essere scambiato, risparmiando un byte.

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
Questa risposta è legata per il più breve e più vecchia di circa un'ora e mezza, quindi la accetto.
Isaacg,

Grazie! Non potevo quasi immaginare che MATL sarebbe stato legato a Pyth. È un linguaggio così difficile da battere, buon lavoro nel progettarlo!
Luis Mendo,

11

Retina , 59 58 byte

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

Riceve input in unario . L'ingresso 7 (ovvero 1111111) impiega un po 'di tempo ma si completa in meno di un minuto. Non andrei molto oltre.

Provalo online.

Spiegazione

Una diversa caratterizzazione dei numeri di Motzkin è il numero di stringhe di tre diversi caratteri, in cui due di essi sono correttamente bilanciati (da qui la stretta relazione con i numeri catalani, che sono gli stessi senza il terzo carattere che è indipendente dal bilanciamento).

Gruppi di bilanciamento del NET sono abbastanza bravo a rilevare le stringhe correttamente abbinate, così abbiamo semplicemente generiamo tutti stringhe di lunghezza N(utilizzando _, <e >come i tre caratteri) e poi contiamo quanti di questi sono correttamente bilanciata. Ad esempio per N = 4le stringhe valide sono:

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

Rispetto alla definizione nella sfida, _corrisponde a un (1,0)passo, <verso (1,1)e >verso (1,-1).

Per quanto riguarda il codice effettivo, :viene utilizzato come separatore tra le diverse stringhe. Il secondo regex è solo una forma golfata del regex .NET standard per stringhe bilanciate .

Qualcosa da notare è che c'è solo un singolo :inserito tra le stringhe in ogni passaggio, ma la seconda regex corrisponde a un inizio e un finale :(e poiché le corrispondenze non possono sovrapporsi, ciò significa che le stringhe adiacenti generate da un modello nell'ultimo passaggio non possono corrispondere entrambe ). Tuttavia, questo non è un problema, perché al massimo uno di questi tre può mai eguagliare:

  • Se la stringa termina in _corrispondenza, il prefisso senza quello _è già bilanciato correttamente e <o >eliminerebbe tale equilibrio.
  • Se la stringa termina in >corrispondenza, la stringa è bilanciata con quella >, quindi _o <eliminerebbe tale equilibrio.
  • Le stringhe che finiscono in <non possono mai essere bilanciate.

È un peccato che "\" abbia un significato speciale, altrimenti usare i caratteri "_ / \" si adatterebbe meglio allo spirito della domanda.
Neil,

9

Python 2, 51 byte

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

Utilizza la formula di Mathworld

inserisci qui la descrizione dell'immagine

Salva i caratteri inserendo il M[n-1]termine nella somma come k=n-1, che dà M[-1]*M[n-1], M[-1]=1come parte della condizione iniziale.

Modifica: un carattere più breve scrivendo la somma in modo ricorsivo:

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

Altri approcci che si sono rivelati più lunghi:

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 byte

Ls*V+KyMb1+t_K1

Questo definisce una funzione y. Provalo online: dimostrazione

Spiegazione:

Lascia che y[n]sia il nnumero numero Motzkin. Calcolo y[n]con la formula

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

Si noti che il primo vettore è più grande del secondo (tranne che per il calcolo y[0]). In questo caso, Pyth ignora automaticamente 1 alla fine del primo vettore, in modo che entrambi i vettori abbiano la stessa lunghezza.

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)

Questa formula è una variazione di una delle formule elencate su OEIS. Potrebbe essere un po 'stupido. A causa dell'1 alla fine del primo vettore (che rende le lunghezze disuguali), in realtà non devo dare alla ricorsione un caso base. E avevo speranze che i due +...1s potessero essere giocati a golf in qualche modo. Si scopre che non posso.

È possibile definire una ricorsione simile con un prodotto punto di vettori di uguale lunghezza e definire il caso base y[0] = 1con lo stesso numero di byte.


8

CJam (20 byte)

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

Demo online

Come ha osservato Mego nei commenti sulla domanda, questo è strettamente correlato ai numeri catalani: cambia .5in 1e compensa l'indice di uno (o semplicemente rimuovi il .5tutto e lascia invariato l'indice) per ottenere numeri catalani.

La ricorrenza utilizzata è

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

dalla pagina OEIS. La ricorrenza corrispondente per i numeri catalani è elencata come

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


6

Scherzi a parte, 21 byte

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

Prende in prestito un po 'di codice dalla soluzione di numeri catalani di quintopia , in particolare il miglioramento che ho apportato nei commenti.

Uso la seguente formula:

formula motzkin

Dato che nCkè 0 per k > n, somma tutto n-1, poiché quei valori saranno tutti 0 e quindi non influenzano la somma.

Provalo online

Spiegazione:

,;╗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)cosa fa adesso?
Addison Crump,

@FlagAsSpam C(n,k) = nCko il numero di combinazioni di karticoli da un pool di narticoli.
Mego

Oh, ha molto più senso di quello che pensavo fosse. +1.
Addison Crump,

@FlagAsSpam Non credo di voler sapere cosa pensavi fosse ...
Mego

5

R, 64 byte

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

Utilizza anche la formula Mathworld della risposta del pitone di @ xnor . Grazie alle regole di precedenza, 2:n-2è equivalente a 0:(n-2).

Casi 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 byte

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

Per divertimento, ecco una versione da 37 byte

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

e versione a 52 byte

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

4

Gelatina , 17 14 13 byte

×US;
1;HÇƓ¡1ị

Questo utilizza la relazione di ricorrenza dalla risposta di @ PeterTaylor . Provalo online!

Come funziona

×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 byte

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

Una versione da 35 byte:

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

2

Pari / GP , 38 36 26 byte

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

Provalo online!

Usando l'equazione (11) di MathWorld :

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

dove è un coefficiente trinomiale . Per definizione, è il coefficiente di nell'espansione di . ( n(nk)2xn+k(1+x+x2)n(nk)2xn+k(1+x+x2)n


A 14-byte Samau funzione utilizzando la prima definizione del coefficiente trinomio: );;7 2D$ⁿ$)╡$÷. Non lo posterò come risposta perché la lingua è più recente della domanda.
alephalpha,

Pubblicandolo va bene, devi solo aggiungere una dichiarazione di non responsabilità che l'invio non è idoneo a vincere perché, come hai detto, la lingua è più recente della domanda.
Alex A.

2

05AB1E , 13 12 byte

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

Provalo online!

Mentre la maggior parte delle risposte utilizza una formula o una relazione di ricorrenza, questo è un semplice approccio di conteggio.

Ogni possibile percorso attraverso la griglia è rappresentato dall'elenco delle sue coordinate y. Per n segmenti, ci sono un totale di (n + 1) punti, ma il primo e l'ultimo sono necessariamente 0, quindi lascia (n-1) punti da specificare.

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

Ora abbiamo un elenco di percorsi (non ancora compreso lo 0 iniziale e finale). Per costruzione, nessuno di loro scende mai sotto lo 0. Tuttavia, alcuni di essi hanno pendenze illegali (es. Salta da 0 a 2), quindi dobbiamo filtrarli.

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

Ÿè la gamma fluttuante integrata. Se c'è una coppia di numeri non adiacenti, riempirà i numeri mancanti (ad es. [0, 2] diventa [0, 1, 2]). Solo i percorsi legali rimarranno invariati.

Un modo forse più intuitivo per verificare la presenza di pendenze illegali sarebbe üαà(affermare che il massimo delle differenze assolute a coppie è uguale a 1). Tuttavia, questo manca il percorso flat [0, 0, ... 0], che costa un byte extra da correggere.

Infine, si noti che il codice effettivo utilizza dove viene utilizzata questa spiegazione 0.ø. Invece di circondare il percorso con 0, questo circonda l'input implicito con due copie del percorso. In questo modo il sistema di coordinate viene capovolto e rovesciato, ma per il resto è equivalente.


2

Stax , 12 byte

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

Esegui ed esegui il debug

Non so come fare fantasiose composizioni matematiche, ma questo si basa essenzialmente su una costruzione di programmazione dinamica

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

Ruby, 50 anni

implementazione diretta della relazione di ricorrenza.

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

1

Brain-Flak , 90 byte

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

Provalo online!

(n0)2(n2)2(nk)2Cn=(2nn)(2nn+1)


0

ES6, 44 byte

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

Porta semplice della soluzione Python ricorsiva di @xnor. Necessità n<1?1:perché n<1||renderebbe il f(0)ritorno true.


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.