您的函数采用自然数,并返回具有除数在内的最小除数的最小自然数,包括它本身。
例子:
f(1) = 1 [1]
f(2) = 2 [1, 2]
f(3) = 4 [1, 2, 4]
f(4) = 6 [1, 2, 3, 6]
f(5) = 16 [1, 2, 4, 8, 16]
f(6) = 12 [1, 2, 3, 4, 6, 12]
...
该函数不必返回除数列表,仅在此处提供示例。
您的函数采用自然数,并返回具有除数在内的最小除数的最小自然数,包括它本身。
例子:
f(1) = 1 [1]
f(2) = 2 [1, 2]
f(3) = 4 [1, 2, 4]
f(4) = 6 [1, 2, 3, 6]
f(5) = 16 [1, 2, 4, 8, 16]
f(6) = 12 [1, 2, 3, 4, 6, 12]
...
该函数不必返回除数列表,仅在此处提供示例。
Answers:
f←{({+/⍵=⍵∧⍳⍵}¨⍳2*⍵)⍳⍵}
定义一个函数f
,然后可以使用该函数来计算数字:
> f 13
4096
> f 14
192
该解决方案利用LCM(n,x)== n的事实,如果x除以n。因此,该块{+/⍵=⍵∧⍳⍵}
仅计算除数的数量。此函数适用于从1到2 ^ d的 所有数字¨⍳2*⍵
。然后在结果列表中搜索d本身(⍳⍵
),即所需函数f(d)。
{⍵⍳⍨(+/⊢=⊢∧⍳)¨⍳2*⍵}
f
。
{.{\.,{)1$\%},,-=}+2@?,?}:f;
编辑:如果我们将搜索范围限制为<2 ^ n,则可以保存单个字符,这要感谢Peter Taylor的想法。
先前版本:
{.{\)..,{)1$\%},,-@=!}+do}:f;
尝试在GolfScript中在线运行。
例子:
13 f p # => 4096
14 f p # => 192
15 f p # => 144
该代码本质上包含三个块,下面各行将对其进行详细说明。
# Calculate numbers of divisors
# .,{)1$\%},,-
# Input stack: n
# After application: D(n)
., # push array [0 .. n-1] to stack
{ # filter array by function
) # take array element and increase by one
1$\% # test division of n ($1) by this value
}, # -> List of numbers x where n is NOT divisible by x+1
, # count these numbers. Stack now is n xd(n)
- # subtracting from n yields the result
# Test if number of divisors D(n) is equal to d
# {\D=}+ , for D see above
# Input stack: n d
# After application: D(n)==d
{
\ # swap stack -> d n
D # calculate D(n) -> d D(n)
= # compare
}+ # consumes d from stack and prepends it to code block
# Search for the first number which D(n) is equal to d
# .T2@?,? , for T see above
# Input stack: d
# After application: f(d)
. # duplicate -> d d
T # push code block (!) for T(n,d) -> d T(n,d)
2@? # swap and calculate 2^d -> T(n,d) 2^d
, # make array -> T(n,d) [0 .. 2^d-1]
? # search first element in array where T(n,d) is true -> f(d)
1
。
的Python:64
修改Bakuriu的解决方案,并结合grc的建议以及Plannapus的R解决方案的技巧,我们得到:
f=lambda n,k=1:n-sum(k%i<1for i in range(1,k+1))and f(n,k+1)or k
蟒蛇:66
f=lambda n,k=1:n==sum(k%i<1for i in range(1,k+1))and k or f(n,k+1)
上面的代码将RuntimeError: maximum recursion depth exceeded
在CPython中使用少量输入来引发a ,甚至将限制设置为很大的数量也可能会带来一些问题。在优化尾部递归的python实现中,它应该可以正常工作。
以下79字节的解决方案是一个更详细的版本,不应具有此类限制:
def f(n,k=1):
while 1:
if sum(k%i<1for i in range(1,k+1))==n:return k
k+=1
if else
用and or
和==1
用<1
:f=lambda n,k=1:n==sum(k%i<1for i in range(1,k+1))and k or f(n,k+1)
sum(k%-~i<1for i in range(k))
f=lambda n,k=1:n==sum(k%-~i<1for i in range(k))or-~f(n,k+1)
保存7个字节。
(For[i=1,DivisorSum[++i,1&]!=#,];i)&
用法:
(For[i=1,DivisorSum[++i,1&]!=#,];i)&@200
结果:
498960
编辑
一些解释:
DivisorSum [n,form]表示除以n的所有i的form [i]之和。
当form[i]
我使用该函数时1 &
,该函数总是返回1
,因此可以用简洁的方式有效地计算除数之和。
DivisorSum
返回的结果(除数的总和),但是我不认为这对回答所提出的问题有什么帮助。您能解释一下它是如何工作的。顺便说一句,我认为您应该包括n = 200的时序数据;考虑到必须检查的所有数字,该功能非常快。
快速又肮脏(易读且不易出错)的解决方案:
f k=head[x|x<-[k..],length[y|y<-[1..x],mod x y==0]==k]
{⍵{⍺=+/0=⍵|⍨⍳⍵:⍵⋄⍺∇⍵+1}1}
Javascript 70
function f(N){for(j=i=m=1;m-N||j-i;j>i?i+=m=j=1:m+=!(i%++j));return i}
确实只有46个有意义的字符:
for(j=i=m=1;m-N||j-i;j>i?i+=m=j=1:m+=!(i%++j))
我可能应该学习一种语法较短的语言:)
N=>eval("for(j=i=m=1;m-N||j-i;j>i?i+=m=j=1:m+=!(i%++j));i")
可以认为它是对早期Haskell解决方案的改进,但它本身就是一个构想(警告:这很慢):
f n=until(\i->n==sum[1|j<-[1..i],rem i j<1])(+1)1
这是一个非常有趣的函数,例如请注意f(p)= 2 ^(p-1),其中p是质数。
n
素数分解成素数(重复),对它们进行降序排序,对每个素数进行递减,用无限个素数序列压缩,然后折叠p^(factor-1)
1<>p=[]
x<>p|mod x p>0=x<>(p+1)|1<2=(div x p<>p)++[p]
f k=product[p^(c-1)|(p,c)<-zip[r|r<-[2..k],2>length(r<>2)](k<>2)]
测试代码:
main=do putStrLn$show$ f (100000::Integer)
这种方法非常快。首先是找到的主要因子k=p1*p2*...*pm
,其中p1 <= p2 <= ... <= pm。那么答案是n = 2^(pm-1) * 3^(p(m-1)-1) * 5^(p(m-2)-1) ...
。
例如,将k = 18分解,我们得到18 = 2 * 3 *3。前三个素数是2、3、5。因此答案n = 2 ^(3-1)* 3 ^(3-1)* 5 ^(2-1)= 4 * 9 * 5 = 180
您可以在下面进行测试ghci
:
*Main> f 18
180
*Main> f 10000000
1740652905587144828469399739530000
*Main> f 1000000000
1302303070391975081724526582139502123033432810000
*Main> f 100000000000
25958180173643524088357042948368704203923121762667635047013610000
*Main> f 10000000000000
6558313786906640112489895663139340360110815128467528032775795115280724604138270000
*Main> f 1000000000000000
7348810968806203597063900192838925279090695601493714327649576583670128003853133061160889908724790000
*Main> f 100000000000000000
71188706857499485011467278407770542735616855123676504522039680180114830719677927305683781590828722891087523475746870000
*Main> f 10000000000000000000
2798178979166951451842528148175504903754628434958803670791683781551387366333345375422961774196997331643554372758635346791935929536819490000
*Main> f 10000000000000000000000
6628041919424064609742258499702994184911680129293140595567200404379028498804621325505764043845346230598649786731543414049417584746693323667614171464476224652223383190000
fl
通过其输出变量获取输入,并通过其输入变量获取输出。
f The list of factors of
the input variable
l has length equal to
the output variable.
这个完全相同的谓词通过其输入变量获取输入并通过其输出变量输出,从而解决了这一难题。
(For[k=1,DivisorSigma[0, k]!= #,k++]; k)&
用法
(For[k = 1, DivisorSigma[0, k] != #, k++]; k) &[7]
(* 64 *)
第一个条目(在将code-golf
标签添加到问题之前。)
一个简单的问题,因为它Divisors[n]
返回n
(n
)的除数并Length[Divisors[n]]
返回这样的除数的数量。**
smallestNumber[nDivisors_] :=
Module[{k = 1},
While[Length[Divisors[k]] != nDivisors, k++];k]
例子
Table[{i, nDivisors[i]}, {i, 1, 20}] // Grid
Length@Divisors@n
现在更短,更快DivisorSigma[0,n]
。
DivisorSigma
。
2*RÆdi
2*RÆdi Main link. Argument: n (integer)
2* Compute 2**n.
R Range; yield [1, ..., 2**n]. Note that 2**(n-1) has n divisors, so this
range contains the number we are searching for.
Æd Divisor count; compute the number of divisors of each integer in the range.
i Index; return the first (1-based) index of n.
2*
呢?是其后的每个数字的除数都大于n吗?
2**(n-1)
{my \a=$=0;a++while $_-[+] a X%%1..a;a}
用法示例:
say (0..10).map: {my \a=$=0;a++while $_-[+] a X%%1..a;a}
(0 1 2 4 6 16 12 64 24 36 48)