我想计算可能被1-20的所有自然数均分的最小可能数;我在R中编写了以下程序,并没有得到所需的输出(相反,我的循环似乎永远不会结束)。
我的计划如下:
a = 21
c = 0
while ( c < 20){
c = 0
n = 1
while ( n < 21 ){
if (a%%n == 0) c = c + 1
n = n+1
}
a = a + 1
}
print (a)
我哪里出错了?
答案 0 :(得分:5)
这是一个更像R的解决方案,使用这个事实,答案将是素数p <= 20
的乘积,每个素数都提升到索引i
,以便p^i <=20
sMult <- function(x)
# calculates smallest number that 1:x divides
{
v <- 1:x
require(gmp) # for isprime
primes <- v[as.logical(isprime(v))]
index <- floor(log(x)/log(primes))
prod(rep(primes,index))
}
哪个收益率:
> sMult(20)
[1] 232792560
> sMult(20)%%1:20
[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
虽然这个解决方案很通用,但应该注意的是,对于大x
,isprime
是概率性的。当然,如果这可能会产生错误的结果,那么您也可能会有一个如此之大的数字,以至于无法准确存储。幸运的是,gmp包实现了一个大整数类bigz
。要将此更改用于函数的最后一行:
prod(as.bigz(rep(primes,index)))
比较以下结果:
> sMult(1000)
[1] Inf
> sMult2(1000)
[1] "7128865274665093053166384155714272920668358861885893040452001991154324087581111499476444151913871586911717817019575256512980264067621009251465871004305131072686268143200196609974862745937188343705015434452523739745298963145674982128236956232823794011068809262317708861979540791247754558049326475737829923352751796735248042463638051137034331214781746850878453485678021888075373249921995672056932029099390891687487672697950931603520000"
答案 1 :(得分:3)
目前尚不清楚您使用n
和c
这是一个重构的例程(我不知道R语法,所以你需要转换它,但逻辑仍然是相关的)
对于一个可被所有1..20均分的数字,它可以被所有素数&lt; = 20(显然)均匀地除除,因此它必须可以被素数的乘积除以&lt; = 20(即9699690)
所以只测试9699690的倍数是必要的。
在20开始测试,以便循环中断更快,净迭代更少
如果答案是&gt;,您应该在ans上添加溢出检查。 ans的数据类型的最大值
ans = 9699690
Do
Found = True
For i = 20 To 2 Step -1
If ans Mod i <> 0 Then
Found = False
ans = ans + 9699690
Exit For
End If
Next
If i < best Then best = i
If Found Then Exit Do
Loop
Debug.Print ans
答案 2 :(得分:2)
使用Chris的逻辑只测试9699690的大量我可以找到答案:
found <- FALSE
test <- 9699690
while(!found)
{
test <- test + 9699690
found <- all(test%%(1:20)==0)
}
cat("The number is: ",test,"\n")
The number is: 232792560
至于为什么OP代码不起作用,这可能是你感兴趣的而不是解决这个小谜题,代码只有一个小问题,它可能不是你的事情。如果我们在真正答案之前输入一个值:
a = 232792559
c = 0
while ( c < 20){
c = 0
n = 1
while ( n < 21 ){
if (a%%n == 0) c = c + 1
n = n+1
}
a = a + 1
}
print (a)
[1] 232792561
我们得到的太多,这是因为即使答案是正确的,您也会1
添加a
。将它移动到外环的前面并且它可以工作。它看起来像是一个无限循环,因为在计算这样的事情时,它在R中太慢了。在R中,我们需要做的事情与C之类的语言不同,因为R代码没有编译(意味着循环需要很长时间)并且针对矢量化输入进行了优化。
查看你的代码告诉我你是R的新手,但也许有其他语言的经验,但是这种经验在R中对你没那么多帮助。我建议你阅读如何对事物进行矢量化。