Sumas circulares limitadas

10

Desafío

Imaginemos una Ntupla de enteros entre 0 e Minclusive, y llamémoslo F.

Hay (M + 1) ** Nposibles Fs en total.

¿Cuántos Fs satisfacen todas las siguientes desigualdades (el índice se basa en uno)?

  • F[n] + F[n+1] <= M para 1 <= n < N
  • F[N] + F[1] <= M

Escribir un programa o función que toma dos números enteros positivos N y My envía la respuesta en cualquier forma conveniente.

Casos de prueba

(N,M) => Answer

(1,1) => 1
(2,1) => 3
(3,1) => 4
(4,1) => 7

(1,2) => 2
(2,2) => 6
(3,2) => 11
(4,2) => 26

(10,3) => 39175
(10,4) => 286555
(10,5) => 1508401

(25,3) => 303734663372
(25,4) => 43953707972058
(25,5) => 2794276977562073

(100,3) => 8510938110502117856062697655362747468175263710
(100,4) => 3732347514675901732382391725971022481763004479674972370
(100,5) => 60964611448369808046336702581873778457326750953325742021695001

Explicación

M (max value of element) = 1

F[1] + F[1] <= 1; F = [0]
(1,1) => 1

F[1] + F[2] <= 1; F = [0,0], [0,1], [1,0]
(2,1) => 3

F = [0,0,0], [0,0,1], [0,1,0], [1,0,0]
(3,1) => 4

F = [0,0,0,0], [0,0,0,1], [0,0,1,0], [0,1,0,0], [0,1,0,1], [1,0,0,0], [1,0,1,0]
(4,1) => 7

---

M = 2

F[1] + F[1] <= 2; F = [0], [1]
(1,2) => 2

F = [0,0], [0,1], [0,2], [1,0], [1,1], [2,0]
(2,2) => 6

F = [0,0,0], [0,0,1], [0,0,2], [0,1,0], [0,1,1], [0,2,0], [1,0,0], [1,0,1],
[1,1,0], [1,1,1], [2,0,0]
(3,2) => 11

(4,2) => 26 (left as exercise for you)

Reglas

  • Este es un desafío de . La complejidad temporal de su código debe ser polinómica MyN (por ejemplo, no puede generar todas las (M + 1) ** Ntuplas y luego verificar la condición). Explique su enfoque en su presentación.
  • Se aplican reglas estándar de . La respuesta más corta en bytes gana.
Bubbler
fuente

Respuestas:

7

Python con numpy , 59 bytes

lambda M,N:trace(mat(tri(M+1)[::-1])**N)
from numpy import*

Pruébalo en línea!

Utiliza la multiplicación de matrices para contar caminos. Si la precisión de flotación es un problema, matpodría especificar mat(...,int).

xnor
fuente
Usar mat(...,int)no parece funcionar para los n=100casos. El método es correcto (el uso de sympy para sumar los poderes de las raíces del polinomio característico funciona, por ejemplo), pero numpy falla en algún lugar a medida que aumentan los números (¿tal vez es el **operador de poder?)
Jonathan Allan
4

Pyth , 27 bytes

.N?Ys:RTtYh-QNgQ+NTs:Rdtszh

Demostración

Espera entrada en el formato:

M
N

Esta es una programación dinámica clásica, sobre el extremo izquierdo de los valores establecidos hasta ahora, el extremo derecho y el tamaño actual de la brecha.

Cómo funciona, en pseudocódigo / Python:

.N          | define memoized fill(left, right, gap):
?           | if cap > 0 then
s:RTtY      | sum(fill(i, right, gap - 1)
h-QN        |     for i in range(M - left + 1))
gQ+NT       | else M >= left + right
            | output:
s:Rdtsz     | sum(fill(i, i, N - 1)
h           |     for i in range(M + 1))

Qse usa para M, zse usa para N, :es fill, Nes left, Tes right, Yes gap.

isaacg
fuente
4

MATL , 13 12 bytes

Q:&>~PiY^Xds

Pruébalo en línea! Esta es una traducción directa de la respuesta de Python de xnor y mi primera respuesta MATL, por lo que probablemente no sea óptima. Por ejemplo, es probable que haya una forma más corta de obtener una matriz triangular superior izquierda de unos que t&lYRP. Editar: Y resulta que hay, a saber :&>~P. ¡Gracias a Luis Mendo por -1 byte!

               M is the first input and N the second
Q:             increment M and generate range from 1 to M+1
  &>           compare vector element wise with itself with greater-than function
               results in a upper-right triangular matrix
    ~          inverse to get lower-left triangular matrix
     P         flip rows to get upper-left triangular matrix
      i        input N
       Y^      take the matrix to the power of N
         Xds   compute the sum of the main diagonal
Laikoni
fuente
@LuisMendo ¡Gracias! ¿Aunque es solo un byte o hay algo más que se puede soltar?
Laikoni
1
No, eso es todo, no puedo contar :-D
Luis Mendo
2

Stax , 17 bytes

°(√&╒íƽ╨⌂'├╖▼1_Z

Ejecutar y depurarlo

Desempaquetado, sin golf y comentado, se ve así.

^1](    [1, 0, ... 0] with M zeroes
:)      get all rotations of the array
{       begin block
  {:+rm map each array to reverse(prefixSums(arr))
},v*    execute preceding block N-1 times
F       for each array, execute the rest of the program
  iT    remove the last i elements from the array, where i is the iteration index
  F+    add the remaining elements to the running total
        implicitly print output

Ejecute este

recursivo
fuente
2

R , 72 bytes

function(M,N)sum(diag(Reduce(`%*%`,rep(list(outer(0:M,0:M,"+")<=M),N))))

Pruébalo en línea!

Puertos xnor enfoque.

Falla para casos de prueba más grandes ya que R solo tiene soporte entero de 32 bits (se convierten a doubleuna vez que se alcanza el valor int máximo), por lo quegmp lo que sería necesario u otra biblioteca aritmética de precisión arbitraria.

Curiosamente, R carece de un operador de potencia de matriz, como ^siempre se aplica por elementos.

Giuseppe
fuente
En realidad, hay un %^%operador implementado correctamente en el paquete expmque permitiría -5 bytes , pero desafortunadamente, no está disponible en TIO (tuve que probarlo localmente).
Kirill L.
@KirillL. Sí, lo había considerado pero creo que seguiré con mi respuesta de base R. También puede jugar golf hasta 60 bytes al no cargar todo el paquete:function(M,N)sum(diag(expm::`%^%`(outer(0:M,0:M,"+")<=M,N)))
Giuseppe