有多少种方法将N写入M个整数?


12

给定一个整数N,计算将其表示为M个整数> 1 的乘积的多少种方式。

输入只是NM,输出是不同整数组的总数。意味着您可以多次使用整数,但是每个组必须是不同的(3 x 2 x 2如果2 x 2 x 3存在,则不计算在内)。

约束条件

1 < N <2 31
1 < M <30

例子

输入可以30 2给出输出3,因为它可以用三种方式表示:

2 x 15
3 x 10
5 x 6

Input 16 3提供output 1,因为只有一个不同的组:

2 x 2 x 4

输入2310 4给出输出10

5 x 6 x 7 x 11
3 x 7 x 10 x 11
3 x 5 x 11 x 14
3 x 5 x 7 x 22
2 x 7 x 11 x 15
2 x 5 x 11 x 21
2 x 5 x 7 x 33
2 x 3 x 11 x 35
2 x 3 x 7 x 55
2 x 3 x 5 x 77

输入15 4给出输出0,因为它不能完成。

规则

应用标准代码高尔夫球漏洞以及用于输入/输出的标准定义。答案可以是功能或完整程序。不允许使用用于分解和/或分区的内置功能,但其他功能很好。代码以字节为单位。


分区是什么意思?
Optimizer

@Optimizer将列表分组为不重叠的子列表。一些语言内置了这种语言,例如Mathematica
Geobits,2015年

有时间限制吗?对于M的较大值,一种特别幼稚的算法可能要花费几个世纪的时间。简单的事情(例如,注意只能有一个比sqrt(N)大的因子)显然会大有帮助。
级圣河

1
@steveverrill给定N的上限,最大应该只有30个(素数)因数,这可以使事情加速很多。但是,请天真。如果您的算法不太可能在几个小时内提供答案,那么经过充分解释的概念证明可以帮助选民做出决定。
Geobits,2015年

一个允许您在其中做两个列表的笛卡尔乘积的内置函数?
Optimizer

Answers:


5

Pyth - 24 23 22 21字节

没有一个复杂的解决方案。将会打更多的高尔夫球。只是采用列表和过滤器的笛卡尔积。与@optimizer相同的策略(由于他的评论,我猜测是,实际上并没有解密CJam)感谢@FryAmTheEggman 2个字节并用M欺骗。

Ml{m`Sdfqu*GHT1G^r2GH

g用args G和定义一个函数H

M                    function definition of g with args G and H
 l                   length of
  {                  set (eliminates duplicates)
   m                 map
    `Sd              repr of sorted factors so can run set (on bash escape ` as \`)
    f                filter
     q      G        equals first arg
      u*GHT1         reduce by multiplication
     ^     H         cartesian product by repeat second arg
       r2G           range 2 to first arg

除最后一个测试参数外,其他所有参数均工作,但速度太慢,但没有时间限制。


输入可以采用这种格式。
Geobits,2015年

1
Pyth golf技巧:如果您有2个参数,通常会更短一些,M它定义了g2个参数的功能,GH。这就是我得到的:Ml{msdfqu*GHT1G^r2GH。总是很高兴看到另一个Pyth用户:)
FryAmTheEggman

@FryAmTheEggman更新了谢谢。
Maltysen,2015年

1
这似乎为输入提供了错误的答案,该输入72 3返回5,但实际上有6个答案,(2, 2, 18), (2, 3, 12), (2, 4, 9), (2, 6, 6), (3, 3, 8)
isaacg 2015年

1
@isaacg哦,好,我将其还原为我的21个字符的版本。我不认为将其相加是可行的,但似乎可以,因此我将重提。谢谢你的收获。
Maltysen 2015年

9

Python 3、59

f=lambda N,M,i=2:i<=N and f(N/i,M-1,i)+f(N,M,i+1)or-~M==N<2

我们算出潜在的除数i。将附加参数i作为允许的最低除数,则核心递归关系为

f(N,M,i)=f(N/i,M-1,i)+f(N,M,i+1)

对于每个i,我们都选择包括它(可能重复),在这种情况下,我们将所需乘积N除以i并递减M。如果不这样做,我们将增加i1,但仅i<N当时才增加,因为没有大于的使用检查除数N

当最小除数i超过时N,将没有更多的潜在除数。因此,我们通过查看M==0 and N==1,,或等效于M+1==N==1M+1==N<2,自何时以来是否成功来检查M+1==N相互值是否保证为正整数(这要归功于FryAmTheEggman)。

此代码将N在大多数系统上导致大约1000 的堆栈溢出,但是您可以在Stackless Python中运行它来避免这种情况。而且,由于它的指数递归分支,它非常慢。


我认为您可以使用-~M==N<2
FryAmTheEggman 2015年

@FryAmTheEggman我认为这会产生假阳性,但实际上它的工作原理,由于联合制约MN。谢谢!
xnor 2015年

4

Ruby,67岁

f=->n,m,s=2,r=0{m<2?1:s.upto(n**0.5){|d|n%d<1&&r+=f[n/d,m-1,d]}&&r}

对于递归定义,实际上是相当有效的。对于[d,q]n的每个除数对d,我们将的结果相乘,取较小的对f[q,m-1]。棘手的是,在内部调用中,我们将因数限制为大于或等于d的因数,这样我们就不会结束重复计算。

1.9.3-p327 :002 > f[30,2]
 => 3 
1.9.3-p327 :003 > f[2310,4]
 => 10 
1.9.3-p327 :004 > f[15,4]
 => 0 
1.9.3-p327 :005 > f[9,2]
 => 1 

2

CJam,48个字节

这可能会短很多,但是我添加了某些检查以使其M在在线编译器上正常运行。

q~\:N),2>{N\%!},a*{_,2/)<m*{(+$}%}*{1a+:*N=},_&,

在这里在线尝试


这是越野车。尝试输入2 1。预期成果:1,实际输出:0
彼得·泰勒

@PeterTaylor叹息。固定。
Optimizer

2

T-SQL 456 373

我敢肯定,当输入接近于大输入时,这会中断。

感谢@MickyT通过CONCAT和SELECTing而不是多个SET帮助保存了许多字符。

CREATE PROC Q(@N INT,@M INT)AS
DECLARE @ INT=2,@C VARCHAR(MAX)='SELECT COUNT(*)FROM # A1',@D VARCHAR(MAX)=' WHERE A1.A',@E VARCHAR(MAX)=''CREATE TABLE #(A INT)WHILE @<@N
BEGIN
INSERT INTO # VALUES(@)SET @+=1
END
SET @=1
WHILE @<@M
BEGIN
SELECT @+=1,@C+=CONCAT(',# A',@),@D+=CONCAT('*A',@,'.A'),@E+=CONCAT(' AND A',@-1,'.A<=A',@,'.A')END
SET @C+=CONCAT(@D,'=',@N,@E)EXEC(@C)

我想对此表示赞同,但是我找不到一种简单的方法来对其进行测试。有任何想法吗?第三方确认它也很好。
Geobits,2015年

我在运行时遇到了一些转换错误(2012)。他们似乎来自这些陈述,SET @C+=',# A'+@以及SET @D+='*A'+@+'.A'SET @E+=' AND A'+(@-1)+'.A<=A'+@+'.A'
MickyT 2015年

您还需要修复SET @C+=@D+'=@N'+@E+' SELECT @'。该@N是内部的报价范围之外使它当你执行@C。另外,我认为您最终将计算重复数
MickyT 2015年

现在,我已经在2012年对其进行了测试。它应该可以工作。
bmark

2
现在效果不错:)在几个地方可以剃一些字符。尝试使用CONCAT构建您的字符串。然后可以删除CONVERTs。试着SELECT @+=1,@C+=CONCAT(...),@D+=CONCAT(...),@E+=CONCAT(...)在你的WHILE循环。如果您保存合理数量
MickyT
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.