使用给定参数k,start,nd写函数count_Kprimes,返回start(包括)和end(包括)之间的k-prime列表。
这是我的尝试:
def count_Kprimes(k, start, nd):
ls = []
for x in range(start, nd + 1):
y = x
l = []
for i in range(2, x + 1):
while y % i == 0:
l.append(i)
y /= i
if len(l) == k:
ls.append(x)
return ls
但是,我的代码需要花费太多时间来处理,我只想简单地编写代码。怎么做到呢?非常感谢你!
此任务取自Codewar
答案 0 :(得分:0)
嗯,无论如何我很乐意解决这个问题。这是一个基于数组逻辑的解决方案
def count_Kprimes(k, start, nd):
x = np.arange(start, nd + 1, dtype=np.float)
# divs will contain all divisors (plus one extra column)
divs = np.ones((x.size, k + 1))
# we have to loop only nd / 2^(k-1) to get all divisors
for i in range(2, int(nd / 2 ** (k - 1)) + 1):
# but each possible divisor "i" may occur up to k times
# we loop until k+1 to catch also number that exceed our target,
# so we can discard them later
for j in range(1, k + 2):
# check for each row (dimension 0) if i is a divisor
# then set the first zero-value in dimension 1 to be this divisor
d = np.prod(divs, axis=1)
divs[[[np.rint(x/d/i)==x/d/i][0],np.argmin(divs[np.rint(x/d/i)==x/d/i], axis=1)]] = i
# The correct result we're looking for is each row that has exactly
# k values != 1 (which equals to exactly one "1" per row)
indices = np.apply_along_axis(lambda x: x[x==1].size == 1, 1, divs)
for val, d in zip(x[indices], divs[indices]):
print "{} = {}".format(int(val), " * ".join([str(int(_)) for _ in d[:-1]]))
count_Kprimes(3, 1, 100)
返回
8 = 2 * 2 * 2
12 = 2 * 2 * 3
18 = 2 * 3 * 3
20 = 2 * 2 * 5
27 = 3 * 3 * 3
28 = 2 * 2 * 7
30 = 2 * 3 * 5
42 = 2 * 3 * 7
44 = 2 * 2 * 11
45 = 3 * 3 * 5
50 = 2 * 5 * 5
52 = 2 * 2 * 13
63 = 3 * 3 * 7
66 = 2 * 3 * 11
68 = 2 * 2 * 17
70 = 2 * 5 * 7
75 = 3 * 5 * 5
76 = 2 * 2 * 19
78 = 2 * 3 * 13
92 = 2 * 2 * 23
98 = 2 * 7 * 7
99 = 3 * 3 * 11