主功率因数分解的除数和


11

任务是计算给定素数分解的数的除数和。

输入值

长度为n的两个数组(或等效的数组),一个包含素数因子,另一个包含相应的指数。

输出量

所有除数的总和(包括数字本身)。

数字240以2、3和5为素数,分别以4、1和1为指数。预期输出为744。

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

计分

以字节为单位的最短代码胜出!

如果您的解决方案的运行时复杂度是O(指数的总和)而不是O(指数的乘积),则您的分数可能会乘以0.8。


这里也有类似的问题,但这不是挑战。我认为这个问题足够有趣。

获胜者将在本周末选出


是素数数组总是必须始终排在第一位,而指数数组必须排在第二位,还是可以假设数组输入是相反的?
Sp3000

你可以假设任何输入格式类同所提出的一个
Moartem

现在无法找到它,但我认为这是projecteuler.net上的类似内容
瑕疵的,2016年

Answers:


3

Pyth,13个字节* 0.8 = 10.4

*Fms^LhdhedCQ

示范。

这个答案与上面的答案有些不同。为了计算数的质数幂的和,而不是使用算术公式,而是显式构造和求和。

例如,在[prime,exponent]对上[2, 4],我们映射2 ^ x0, 1, 2, 3, 4,给出[1, 2, 4, 8, 16],然后求和为31。

然后将结果相乘并打印。

如果正确实现了幂运算,或者存在中间结果缓存,则为O(sum of exponents)


独立实施的,我不认为这是可以计算的第一ñ的力量一个在O(n)的时间,除非你认为乘法是O(1)。
丹尼斯

@Dennis好吧,高阶项占主导地位,因此它可能具有最高阶乘法的rutime,也就是O(n)我们可以假设基数是一个常数。
isaacg 2015年

9

CJam,15个字节* 0.8 = 12

q~.{_@)#(\(/}:*

在线尝试。输入顺序首先是指数列表,然后是素数列表(-3个字节,感谢@Dennis)

对于每个素数对(p, e)找到

(p^(e+1) - 1)/(p - 1)

然后找到所有这些的产品。例如,这将是240

(1 + 2 + 4 + 8 + 16)(1 + 3)(1 + 5) = 31 * 4 * 6 = 744

根据求幂的方式,这可能比更好O(sum of exponents)


6

APL,18 13字节* 0.8 = 10.4

×/(1-⊣×*)÷1-⊣

这将创建二元函数列,该列采用左边的因子数组和右边的指数。

×/             ⍝ Vector product of
  (1-⊣×*)      ⍝ each factor^(exponent+1)-1
         ÷1-⊣  ⍝ divided by factor-1

在线尝试。请注意,这与Sp3000出色的CJam答案相同

感谢Dennis,节省了5个字节!


2

TI-BASIC,17字节* 0.8 = 13.6

虽然我是独立找到它的,但也使用Sp3000的方法。从输入获取一个列表,从主屏幕获取一个列表。

Input E
prod(AnsAns^∟E-1)/prod(Ans-1

使用prod(两次较小,因为它可以让我们免费使用开放括号。请注意,此答案不支持空数组,因为TI-BASIC中没有空数组。


2

Haskell,38 * 0.8 = 30.4

product$zipWith(\p e->(p*p^e-1)/(p-1))

用法:

product$zipWith(\p e->(p*p^e-1)/(p-1)) [2,3,5] [4,1,1]
744.0

匿名函数使用(p,e)的除数,和p^e通过几何级数之和。将两个列表以该列表压缩在一起作为连接并取结果。

我找不到比算术表达式更短的内容

(p*p^e-1)/(p-1)
sum$map(p^)[0..e]

也许有办法摆脱这种情况(\p e->_)

中缀函数定义的长度相同(38):

p%e=(p*p^e-1)/(p-1)
product$zipWith(%)

2

C ++,111 80 77字节* 0.8 = 61.6

int g(int*p,int*e,int n){return n?g(p+1,e+1,n-1)*(pow(*p,*e-1)-1)/(*p-1):1;}

这将计算(p ^(e + 1)-1)/(p-1)并递归地乘以所有因子。一年前发现自己。

感谢您的帮助,完全忘记了c ++风格的布尔用法。


1
n==0简化为!n-或您可以颠倒结果并仅使用n
Toby Speight 2015年

2

Matlab,53岁

function t=f(x,y)
s=1:prod(x.^y);t=s*~mod(s(end),s)';

例:

>> f([2 3 5], [4 1 1])
ans =
   744

您似乎可以添加0.8的奖金
Moartem

@Moartem谢谢!但是我不确定。我计算出该数字s,然后测试从1到的所有可能的除数s。因此,它是(至少)O(s),可能在O(指数和)与O(指数的乘积)之间
Luis Mendo 2015年

是的,没错,它甚至比O(指数乘积)还要大
Moartem 2015年

1

蟒蛇2,156

from itertools import*
from operator import*
i=input()
print sum(reduce(mul,[a**b for a,b in zip(i[0],p)])for p in product(*map(range,[x+1 for x in i[1]])))

输入值

[[2,3,5],[4,1,1]]

输出量

744

说明

该程序接收2个列表的列表:因子和指数。

i=input() # Receive list of 2 lists: i[0] for factors i[1] for exponents

然后,它创建指数列表的所有可能组合的列表。

[x+1 for x in i[1]] # [4,1,1]->[5,2,2] (to include last element)
map(range,[x+1 for x in i[1]]) # [[0, 1, 2, 3, 4], [0, 1], [0, 1]]
product(*map(range,[x+1 for x in i[1]])) # [(0, 0, 0), (0, 0, 1), ..., (4, 1, 1)]

并压缩以下因素:

zip(i[0],p) for p in product(*map(range,[x+1 for x in i[1]])) # [[(2, 0), (3, 0), (5, 0)], ..., [(2, 4), (3, 1), (5, 1)]]

计算指数幂的因子:

 [a**b for a,b in zip(i[0],p)]for p in product(*map(range,[x+1 for x in i[1]])) # [[1, 1, 1], ..., [16, 3, 5]]

并乘以每个列表(这使我们得到所有除数):

reduce(mul,[a**b for a,b in zip(i[0],p)])for p in product(*map(range,[x+1 for x in i[1]])) # [1, 5, 3, 15, ..., 240]

最后,对所有列表求和并打印:

print sum(reduce(mul,[a**b for a,b in zip(i[0],p)])for p in product(*map(range,[x+1 for x in i[1]]))) # 744

您能否简要解释一下代码的作用(因为我不熟悉python),所以我可以判断代码的复杂性?
Moartem

那是一个聪明的方法,但是复杂性是指数的乘积
Moartem 2015年

@Moartem是的,我没花太多时间来降低复杂性
TheCrypt

1

Python 3中,134 120 117

输入:两个逗号分隔的数组,以逗号分隔。

例:

(2,3,7,11),(4,2,3,2)
21439600
from functools import*
a=eval(input())
print(reduce(int.__mul__,(sum(x**j for j in range(y+1))for x,y in zip(*a)),1))

使用NumPy可以减少到100个字节:

import numpy
a=eval(input())
print(numpy.product([sum(x**j for j in range(y+1))for x,y in zip(*a)]))

1
对于第一个示例,您已经知道,不必导入即可operator使用mul一次,而可以使用它float.__mul__来保存一堆字节。
卡德2015年

1

果冻,无竞争

这个答案是没有竞争的,因为挑战要早于果冻的创建。

5个字节(无奖金)

*PÆDS

在线尝试!

这个怎么运作

*PÆDS    Main link. Left input: p (prime factors). Right input: e (exponents).

*        Elevate the prime factors to the corresponding exponents.
 P       Take the product of all powers.
  ÆD     Find all divisors of the product.
    S    Compute the sum of the divisors.

7个字节(奖金后为5.6个字节)

*‘}’:’{P

这个怎么运作

×*’:’{P  Main link. Left input: p (prime factors). Right input: e (exponents).

 *       Elevate the prime factors to the corresponding exponents.
         This yields p ** e.
×        Multiply the prime factors with the corresponding powers.
         This yields p ** (e + 1).
  ’      Decrement the resulting products.
         This yields p ** (e + 1) - 1.
    ’{   Decrement the prime factors.
         This yields p - 1.
   :     Divide the left result by the right one.
         This yields (p ** (e + 1) - 1) / (p - 1).
      P  Take the product of all quotients.

在线尝试!


1

APL,12个字节* 0.8 = 9.6

×/1++/¨⎕*⍳¨⎕

这将从键盘读取两个列表,首先读取指数,即:

      ×/1++/¨⎕*⍳¨⎕
⎕:
      4 1 1
⎕:
      2 3 5
744

说明:

  • :从键盘上读取列表(指数)
  • ⍳¨:为列表中的每个数字生成一个列表[1..n]
  • ⎕*:从键盘上读取另一个列表(质数),并将每个质数提高到相应列表中的每个指数
  • +/¨:对每个列表求和
  • 1+:在每个结果中添加一个,以补偿x^0每个列表中的缺失
  • ×/:取结果的乘积

1

球拍(方案),65 * 0.8 = 52字节

和其他人一样的算术

(λ(x y)(foldl(λ(m n o)(*(/(-(expt m(+ n 1))1)(- m 1))o))1 x y))

说明:

(λ (x y)    ;defines anonymous function with two inputs
    (foldl    ;recursively applies the following function to all elements of the lists given to an argument given (foldl function argument lists lists lists...)
        (λ (m n o) (* (/ (- (expt m (+ n 1)) 1) (- m 1)) o))    ;an anonymous function representing the same arithmetic used in the CJam answer, then multiplying it with our incrementor
        1 x y))    ;the incrementor argument is 1, and the input lists are the ones provided into the original function

0

Python 2,80字节* 0.8 = 64

假设输入是一个接一个的输入。遵循与Sp3000的CJam答案中概述的相同公式。

print(reduce(float.__mul__,[~-(x**-~y)/~-x for x,y in zip(input(),input())],1)) 

如果不允许这样做,那么我将使用它作为解决方案,获得84字节* 0.8 = 67.2。的分数。输入应以逗号分隔,即[2,3,5],[4,1,1]

k=input()
print(reduce(float.__mul__,[~-(x**-~y)/~-x for x,y in zip(k[0],k[1])],1))

Psst。嘿! 这是我正在研究的S​​ymbolic中可能的解决方案:Ƥ(П([~-(x**-~y)/~-xϝx,yϊʐ(Ί,Ί)],1))


0

Mathematica,40个字节

Total[Outer@@{*}~Join~(#^0~Range~#2),3]&

无需使用任何处理除数的内建函数,即可与线程中的其他mathematica解决方案区分开。

输入为(使用示例) [{2, 3, 5}, {4, 1, 1}]


0

Perl 5,96个字节

显然,这是不成功的,但我决定为娱乐而写。

这是一个子例程:

{($b,$e)=@_;$s=1;map$s*=$b->[$_]**$e->[$_],0..@$b-1;$_=1x$s;for$j(1..$s){$i+=$j*/^(.{$j})*$/}$i}

如此看待它:

perl -e'print sub{...}->([2,3,5],[4,1,1])'

这个怎么运作:

  • ($b,$e)=@_读取输入的arrayrefs $b(基数)和$e(指数)。
  • $s=1 初始化产品。
  • map$s*=$b->[$_]**$e->[$_],0..@$b-1乘以$s连续的基指数幂。现在$s是合成数字。
  • $_=1x$s设置$_等于一串$s长的。$i初始化为0。
  • for$j(1..$s){$i+=$j*/^(.{$j})*$/}尝试对$j1 $s到之间的每个数字分解$_,因为$j字符重复了任意次。如果可以,则$j除以$s,然后/^(.{$j})*$/为1(否则为0),并$i以进行扩充$j。因此,我们将$i等大小分区中的分区数相加$_。正如Omar E. Pol所指出的$i我们正在寻找的号码。
  • $i最后返回$i

0

J,14个字节* 0.8 = 11.2

[:*/(^>:)%&<:[

用法

   f =: [:*/(^>:)%&<:[
   2 3 5 f 4 1 1
744
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.