Calculer le nombre de matrices avec les sommes appropriées

12

Lors de la multiplication des monômes dans la base de Milnor pour l'algèbre de Steenrod, une partie de l'algorithme implique l'énumération de certaines "matrices autorisées".

Étant donné deux listes d'entiers non négatifs r 1 , ..., r m et s 1 , ..., s n , une matrice d'entiers non négatifs X

une matrice

est autorisé si

  1. La somme de la jième colonne est inférieure ou égale à s j :

    contrainte de somme de colonne

  2. La somme de la ième ligne pondérée par des puissances de 2 est inférieure ou égale à r i :

    contrainte de somme des lignes

Tâche

Écrivez un programme qui prend une paire de listes r 1 , ..., r m et s 1 , s 1 , ..., s n et calcule le nombre de matrices autorisées pour ces listes. Votre programme peut éventuellement prendre m et n comme arguments supplémentaires si nécessaire.

  • Ces nombres peuvent être saisis dans n'importe quel format souhaité, par exemple regroupés dans des listes ou codés en unaire, ou autre chose.

  • La sortie doit être un entier positif

  • Des échappatoires standard s'appliquent.

Notation

Voici le code golf: la solution la plus courte en octets gagne.

Exemples:

Pour [2]et [1], il existe deux matrices autorisées:

Exemple 1

Pour [4]et [1,1]il existe trois matrices autorisées:

exemple 2

Pour [2,4]et [1,1]il existe cinq matrices autorisées:

exemple 3

Cas de test:

   Input: [1], [2]
   Output: 1

   Input: [2], [1]
   Output: 2

   Input: [4], [1,1]
   Output: 3

   Input: [2,4], [1,1]   
   Output: 5      

   Input: [3,5,7], [1,2]
   Output: 14

   Input: [7, 10], [1, 1, 1]
   Output: 15       

   Input: [3, 6, 16, 33], [0, 1, 1, 1, 1]
   Output: 38      

   Input: [7, 8], [3, 3, 1]
   Output: 44

   Input: [2, 6, 15, 18], [1, 1, 1, 1, 1]
   Output: 90       

   Input: [2, 6, 7, 16], [1, 3, 2]
   Output: 128

   Input: [2, 7, 16], [3, 3, 1, 1]
   Output: 175
capuche
la source
1
OMI, la définition serait plus facile à comprendre si vous perdez la première ligne et colonne des matrices, indexez à partir de 1 et utilisez <= au lieu de ==.
Peter Taylor
D'accord, fera l'affaire. Je viens de copier la définition d'un manuel de mathématiques et elle avait une utilité réelle pour ces entrées.
Hood

Réponses:

3

JavaScript (ES7), 163 octets

f=([R,...x],s)=>1/R?[...Array(R**s.length)].reduce((k,_,n)=>(a=s.map((_,i)=>n/R**i%R|0)).some(c=>(p+=c<<++j)>R,p=j=0)?k:k+f(x,s.map((v,i)=>v-a[i])),0):!/-/.test(s)

Cas de test

NB : J'ai supprimé les deux cas de test les plus longs de cet extrait, mais ils devraient également réussir.

Commenté

f = (                               // f = recursive function taking:
  [R,                               //   - the input array r[] splitted into:
      ...x],                        //     R = next element / x = remaining elements
  s                                 //   - the input array s[]
) =>                                //
  1 / R ?                           // if R is defined:
    [...Array(R**s.length)]         //   for each n in [0, ..., R**s.length - 1],
    .reduce((k, _, n) =>            //   using k as an accumulator:
      (a =                          //     build the next combination a[] of
        s.map((_, i) =>             //     N elements in [0, ..., R - 1]
          n / R**i % R | 0          //     where N is the length of s[]
        )                           //
      ).some(c =>                   //     for each element c in a[]:
        (p += c << ++j)             //       increment j; add c * (2**j) to p
        > R,                        //       exit with a truthy value if p > R
        p = j = 0                   //       start with p = j = 0
      ) ?                           //     end of some(); if truthy:
        k                           //       just return k unchanged
      :                             //     else:
        k +                         //       add to k the result of
        f(                          //       a recursive call to f() with:
          x,                        //         the remaining elements of r[]
          s.map((v, i) => v - a[i]) //         s[] updated by subtracting the values of a[]
        ),                          //       end of recursive call
      0                             //     initial value of the accumulator k
    )                               //   end of reduce()
  :                                 // else:
    !/-/.test(s)                    //   return true if there's no negative value in s[]
Arnauld
la source
1

Gelée , 26 octets

UḄ€Ḥ>⁴
0rŒpṗ⁴L¤µS>³;ÇẸµÐḟL

Un programme complet prenant S , R qui imprime le compte

Essayez-le en ligne!

Comment?

UḄ€Ḥ>⁴ - Link 1, row-wise comparisons: list of lists, M
U      - upend (reverse each)
 Ḅ€    - convert €ach from binary (note bit-domain is unrestricted, e.g. [3,4,5] -> 12+8+5)
   Ḥ   - double (vectorises) (equivalent to the required pre-bit-shift by one)
     ⁴ - program's 2nd input, R
    >  - greater than? (vectorises)

0rŒpṗ⁴L¤µS>³;ÇẸµÐḟL - Main link: list S, list R
0r                  - inclusive range from 0 to s for s in S
  Œp                - Cartesian product of those lists
       ¤            - nilad followed by link(s) as a nilad:
     ⁴              -   program's 2nd input, R
      L             -   length
    ṗ               - Cartesian power = all M with len(R) rows & column values in [0,s]
        µ      µÐḟ  - filter discard if:
         S          -   sum (vectorises) = column sums
           ³        -   program's 1st input, S
          >         -   greater than? (vectorises) = column sum > s for s in S
             Ç      -   call the last link (1) as a monad = sum(2^j × row) > r for r in R
            ;       -   concatenate
              Ẹ     -   any truthy?
                  L - length
Jonathan Allan
la source
1

Wolfram Language (Mathematica) , 101 octets

Laissez Mathematica le résoudre comme un système d'inégalités sur les entiers. J'ai mis en place un tableau symbolique fet fil sur trois ensembles d'inégalités. Join@@aplatit simplement la liste pour Solve.

Length@Solve[Join@@Thread/@{Tr/@(t=f~Array~{q=(l=Length)@#2,l@#})<=#2,2^[email protected]<=#,t>=0},Integers]&

Essayez-le en ligne!

Kelly Lowder
la source
0

Mathematica 139 octets

Tr@Boole[k=Length[a=#]+1;AllTrue[a-Rest[##+0],#>=0&]&@@@Tuples[BinCounts[#,{2r~Prepend~0}]&/@IntegerPartitions[#,All,r=2^Range@k/2]&/@#2]]&

Essayez-le en ligne

Explication: partitionne chacun des r i en puissances de 2, puis transforme tous les tuples avec une décomposition en puissances de deux pour chaque entier, soustrayez les totaux des colonnes de la liste des s i . Comptez le nombre de tuples qui rendent toutes les entrées restantes positives.

capuche
la source
2
il est généralement déconseillé de répondre à votre propre défi jusqu'à ce que d'autres aient déjà soumis dans cette langue.
HyperNeutrino
@HyperNeutrino Je peux le supprimer si vous pensez que c'est une bonne idée. Ce n'est pas un golf très soigné, il est donc très probable que d'autres puissent faire mieux.
Hood
3
Bien que ce ne soit pas une mauvaise chose de pouvoir prouver sa solvabilité, je ne recommande pas de gâcher la solution aussi rapidement. Peut-être attendre une semaine d'abord ou quelque chose.
Erik the Outgolfer
Dois-je donc le supprimer ou le laisser maintenant que je l'ai posté?
Hood
Je le laisserais. Pace Erik Je ne pense pas que cela gâche quoi que ce soit: l'existence d'une solution est évidente du fait que les matrices respectant la contrainte de somme des colonnes sont finies et facilement générées.
Peter Taylor