通函有限公司


10

挑战

让我们想象一个N介于0到0之间的整数元组M,并将其称为F

总共(M + 1) ** N可能有F

有多少个这样的Fs满足以下所有不等式(索引基于一)?

  • F[n] + F[n+1] <= M 对于 1 <= n < N
  • F[N] + F[1] <= M

编写一个使用两个正整数 NM以任何方便的形式输出答案的程序或函数。

测试用例

(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

说明

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)

规则

  • 这是一个挑战。代码的时间复杂度应为M和的多项式N(例如,您不能生成所有(M + 1) ** N元组,然后检查条件)。请在您的提交中说明您的方法。
  • 适用标准规则。以字节为单位的最短答案将获胜。

Answers:


7

带有numpy的Python,59个字节

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

在线尝试!

使用矩阵乘法来计数路径。如果浮点精度是一个问题,则mat可以指定mat(...,int)


使用mat(...,int)似乎不适用于这种n=100情况。该方法是正确的(例如,使用sympy对特征多项式的根的幂进行求和确实可行),但是随着数字的增加,numpy在某些地方出错(也许是**幂运算符?)
Jonathan Allan

4

Pyth,27个字节

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

示范

期望以以下格式输入:

M
N

这是经典的动态编程,到目前为止设置的值的左端,右端和当前间隙的大小都超过了。

在伪代码/ 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))

Q用于Mz用于N:fillNleftTrightYgap


4

MATL13 12字节

Q:&>~PiY^Xds

在线尝试!这是xnor的Python答案和我的第一个MATL答案的直接翻译,因此很可能不是最佳的。例如,获得的左上三角矩阵的方法可能更短t&lYRP编辑:事实证明那里是:&>~P。感谢Luis Mendo提供-1个字节!

               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谢谢!虽然只有一个字节,或者还有其他可以丢弃的字节?
莱科尼

1
不,就是这样,我不能指望:-D
路易斯·门多

2

Stax,17 个字节

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

运行并调试

拆开包装,松开包装并进行评论,看起来像这样。

^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

运行这个


2

R,72个字节

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

在线尝试!

移植xnor的方法。

由于R仅具有32位整数支持(double一旦达到最大int值,它们就会gmp强制转换为整数),因此无法用于较大的测试用例,因此将需要使用或另一个任意精度的算法库。

奇怪的是,R缺少矩阵幂运算符,因为它^总是按元素应用。


实际上,%^%程序包expm中有一个正确实现的运算符,该运算符允许-5个字节,但是不幸的是,它在TIO上不可用(我必须在本地进行测试)。
Kirill L.

@KirillL。是的,我曾经考虑过,但我认为我会坚持我的基本R回应。您也可以通过不装入整个程序包来打高尔夫球至60字节:function(M,N)sum(diag(expm::`%^%`(outer(0:M,0:M,"+")<=M,N)))
朱塞佩
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.