计算R程序

时间:2011-06-27 09:08:47

标签: r infinite-loop

我想计算可能被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)

我哪里出错了?

3 个答案:

答案 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

虽然这个解决方案很通用,但应该注意的是,对于大xisprime是概率性的。当然,如果这可能会产生错误的结果,那么您也可能会有一个如此之大的数字,以至于无法准确存储。幸运的是,gmp包实现了一个大整数类bigz。要将此更改用于函数的最后一行:

prod(as.bigz(rep(primes,index)))

比较以下结果:

> sMult(1000)
[1] Inf
> sMult2(1000)
[1] "7128865274665093053166384155714272920668358861885893040452001991154324087581111499476444151913871586911717817019575256512980264067621009251465871004305131072686268143200196609974862745937188343705015434452523739745298963145674982128236956232823794011068809262317708861979540791247754558049326475737829923352751796735248042463638051137034331214781746850878453485678021888075373249921995672056932029099390891687487672697950931603520000"

答案 1 :(得分:3)

目前尚不清楚您使用nc

做了什么

这是一个重构的例程(我不知道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中对你没那么多帮助。我建议你阅读如何对事物进行矢量化。