Sommes limitées circulaires


10

Défi

Imaginons un N-tuple d'entiers compris entre 0 et Minclus, et appelons-le F.

Il y a (M + 1) ** Ndes Fs possibles au total.

Combien de ces Fvaleurs satisfont à toutes les inégalités suivantes (l'indice est à base unique)?

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

Ecrire un programme ou une fonction qui prend deux nombres entiers positifs N et Met fournit la réponse sous quelque forme que pratique.

Cas de test

(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

Explication

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)

Règles

  • Il s'agit d'un défi de . La complexité temporelle de votre code doit être polynomiale MetN (par exemple, vous ne pouvez pas générer tous les (M + 1) ** Ntuples, puis vérifier la condition). Veuillez expliquer votre approche dans votre soumission.
  • Les règles de standard s'appliquent. La réponse la plus courte en octets l'emporte.

Réponses:


7

Python avec numpy , 59 octets

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

Essayez-le en ligne!

Utilise la multiplication matricielle pour compter les chemins. Si la précision du flottement est un problème, le matpourrait spécifier mat(...,int).


L'utilisation mat(...,int)ne semble pas fonctionner pour les n=100cas. La méthode est correcte (utiliser sympy pour additionner les puissances des racines du polynôme caractéristique fonctionne, par exemple), mais numpy va mal quelque part lorsque les nombres augmentent (peut-être que c'est l' **opérateur de puissance?)
Jonathan Allan

4

Pyth , 27 octets

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

Manifestation

Attend une entrée au format:

M
N

Il s'agit d'une programmation dynamique classique, sur l'extrémité gauche des valeurs définies jusqu'à présent, l'extrémité droite et la taille actuelle de l'écart.

Comment ça marche, en pseudocode / 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))

Qest utilisé pour M, zest utilisé pour N, :est fill, Nest left, Test right, Yest gap.


4

MATL , 13 12 octets

Q:&>~PiY^Xds

Essayez-le en ligne! Ceci est une traduction directe de la réponse Python de xnor et de ma première réponse MATL, donc ce n'est probablement pas optimal. Par exemple, il existe probablement un moyen plus court pour obtenir une matrice triangulaire supérieure gauche que celles t&lYRP. Edit: Et il s'avère qu'il y a, à savoir :&>~P. Merci à Luis Mendo pour -1 octet!

               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

@LuisMendo Merci! Bien que ce ne soit qu'un octet ou y a-t-il autre chose qui peut être supprimé?
Laikoni

1
Non, c'est ça, je ne peux pas compter :-D
Luis Mendo

2

Stax , 17 octets

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

Exécuter et déboguer

Déballé, non golfé et commenté, il ressemble à ceci.

^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

Exécutez celui-ci


2

R , 72 octets

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

Essayez-le en ligne!

Ports xnor approche.

Échoue pour les cas de test plus importants car R ne prend en charge que les entiers 32 bits (ils sont convertis en doubleune fois que la valeur int maximale est atteinte), donc l'utilisation d' gmpune autre bibliothèque arithmétique de précision arbitraire serait nécessaire.

Étrangement, R n'a pas d'opérateur de puissance matriciel, comme cela ^s'applique toujours par élément.


En fait, il y a un %^%opérateur correctement implémenté dans le package expmqui autoriserait -5 octets , mais malheureusement, il n'est pas disponible sur TIO (j'ai dû le tester localement).
Kirill L.

@KirillL. ouais, j'avais pensé à ça mais je pense que je vais m'en tenir à ma réponse R de base. Vous pouvez également jouer au golf jusqu'à 60 octets en ne chargeant pas dans le package complet:function(M,N)sum(diag(expm::`%^%`(outer(0:M,0:M,"+")<=M,N)))
Giuseppe
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.