Computing program R

I want to calculate the smallest possible number, which is evenly divided by all natural numbers from 1-20; I wrote the following program in R and do not get the desired result (rather, it seems that my loop almost never ends).

My program is as follows:

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) 

Where am I wrong?

+4
source share
3 answers

Here is a larger R-shaped solution using the fact that the answer is the product of primes p <= 20 , each of which is raised to index i , so 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)) } 

What gives:

 > 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 

While this solution is general, it should be noted that for large x , isprime is probabilistic. Of course, when this can lead to false results, you will also probably have such a large size that it cannot be saved for sure. Fortunately, the gmp package implements the large integer class bigz . To use this change for the final function line, do the following:

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

Compare the following results:

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

It is unclear what you are doing with n and c

Here's a refactored procedure (I don't know the R syntax, so you will need to convert this, but the logic is still allowed)

In order for the number to be evenly divisible by all 1..20, it is also equally divisible by all primes & lt = 20 (obviously), therefore it must be divisible by the product of primes <= 20 (which is 9699690)

Thus, just not recommended to test multiples of 9699690.

Start testing with 20 so that the loop breaks earlier, fewer network iterations

You should add ans overflow check if the answer is> maximum value of ans data type

 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 
+3
source

Using Chris' logic only to test the set of 9699690, I can find the answer with:

 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 

Edit:

As for why OPs code doesn't work, you are most likely interested in, and not solving, this little riddle, there is only one small problem with the code, and that is probably not what you are doing. If we enter one value before the true answer:

 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 

We get too much because you add 1 to a , even if the answer is correct. Move it to the front of the outer loop and it works. It just seems like an infinite loop, because in R it slows down slowly to figure things out. In R, we need to do something different than languages ​​like C, because the R code does not compile (which means the loop takes a lot of time) and is optimized for vectorized input.

Looking at your code, I will tell you that you are new to R, but perhaps experienced in other languages, but this experience will not help you with this. I would advise you to read about how to vectorize things.

+2
source

All Articles