用适当的总和计算矩阵数


12

在Steenrod代数的Milnor基中乘以单项式时,该算法的一部分涉及枚举某些“可允许矩阵”。

给定两个非负整数r 1,...,r ms 1,...,s n的列表,一个非负整数X的矩阵

矩阵

如果是允许的

  1. 第j列的总和小于或等于s j

    列总和约束

  2. 第i行乘以2的幂进行加权的总和小于或等于r i

    行总和约束

任务

编写一个程序,该程序采用一对列表r 1,...,r ms 1s 1,...,s n并计算这些列表的允许矩阵数。如果需要,您的程序可以选择将m和n作为附加参数。

  • 这些数字可以按喜欢的任何格式输入,例如分组到列表中或以一元编码或其他形式输入。

  • 输出应为正整数

  • 有标准漏洞。

计分

这就是代码高尔夫:以字节为单位的最短解决方案获胜。

例子:

对于[2][1],有两个允许的矩阵:

例子1

对于[4][1,1]存在三个允许的矩阵:

例子2

对于[2,4][1,1]有五个允许的矩阵:

例子3

测试用例:

   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

1
如果丢失矩阵的第一行和第一列,从1开始的索引并使用<=而不是==,则IMO的定义将更容易理解。
彼得·泰勒

好吧,会的。我只是从数学教科书中复制了定义,并且对这些条目有实际的用途。
胡德

Answers:


3

JavaScript(ES7),163字节

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)

测试用例

注意:我已从该代码段中删除了两个最耗时的测试用例,但它们也应该通过。

已评论

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[]

1

果冻,26 个字节

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

一个完整的程序,带SR打印计数

在线尝试!

怎么样?

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


0

Mathematica 139字节

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

在线尝试

说明:将每个r i划分为2的幂,然后对于每个整数,将具有一个分解的所有元组分解为2的幂,从s i的列表中减去列总数。计算使所有其余条目均为正的元组数。


2
通常不鼓励您回答自己的难题,直到其他人已经使用该语言提交为止。
HyperNeutrino

@HyperNeutrino如果您认为这是个好主意,可以删除它。这不是超级小心打的球,所以其他人很有可能做得更好。
胡德

3
虽然能够证明它可以解决不是一件坏事,但我不建议这么快就破坏解决方案。也许先等一周。
暴民埃里克(Erik the Outgolfer)'18年

那么我应该删除它还是在发布后保留它?
胡德

我会离开的。佩斯 ·埃里克(Pace Erik),我认为这不会破坏任何东西:解决方案的存在是显而易见的,因为考虑到列和约束的矩阵是有限的并且容易生成。
彼得·泰勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.