Prime number function in R

*爱你&永不变心* 提交于 2019-12-27 15:44:08

问题


I am trying to create a function to test if a given integer is a prime number, I tried using the following:

tpn <- function(prime.num){

    if(prime.num==2){
        print("PRIME")
    } else {

    if(prime.num%%(2:(prime.num-1))!=0){
        print("PRIME")

    } else { 
        print("NOT PRIME")

}}}

This doesn't work, although I cant understand why. I am checking to see if the given number can be divided by any of the integers up to this number with no remainders. If it cant, then the number is prime.

Another solution I found was:

tpn <- function(pn){

    if(sum(pn/1:pn==pn%/%1:pn)==2)
            print("prime")

}

This works. Although, I cant get my head around what sum(pn/1:pn == pn%/%1:pn) == 2 is actually testing for.


回答1:


A number a is divisible by a number b if the result of the division a / b is equal to the result of the integer division a %/% b. Any integer pn can be divided by at least two numbers: 1 and pn. Prime numbers are those than can only be divided by those two. Breaking out the code:

  1. pn / 1:pn are the results of the divisions by 1, 2, ..., pn
  2. pn %/% 1:pn are the results of the integer divisions by 1, 2, ..., pn
  3. sum(pn / 1:pn == pn %/% 1:pn) are how many of these are equal, i.e., the number of integer divisors of pn. If this number is 2, you have a prime.

What was wrong with your code: if needs to test if something is TRUE or FALSE but you were passing it a whole vector. Also, your logic was wrong. It should have been:

is.prime <- function(num) {
   if (num == 2) {
      TRUE
   } else if (any(num %% 2:(num-1) == 0)) {
      FALSE
   } else { 
      TRUE
   }
}

And once you've settled on returning a logical, you can make your code a lot shorter:

is.prime <- function(n) n == 2L || all(n %% 2L:max(2,floor(sqrt(n))) != 0)

(which incorporates @Carl's comment about not checking all numbers.)




回答2:


I just tried the is.prime code example. But with this 3 is not prime ;o)

The improved version uses ceiling instead of the floor operation.

is.prime <- function(n) n == 2L || all(n %% 2L:ceiling(sqrt(n)) != 0)

Best!




回答3:


You may also use the isprime() function in the matlab package. It works also with vector arguments:

library(matlab)

as.logical(isprime(7))
as.logical(isprime(42))

#> as.logical(isprime(7))
#[1] TRUE
#> as.logical(isprime(42))
#[1] FALSE



回答4:


A regular expression to find prime numbers

is.prime <- function(x) {
  x <- abs(as.integer(x))
  !grepl('^1?$|^(11+?)\\1+$', strrep('1', x))
}

(-100:100)[is.prime(-100:100)]
# [1]  -97 -89 -83 -79 -73 -71 -67 -61 -59 -53 -47 -43 -41 -37 -31 -29 -23 -19 -17 -13 -11  -7  -5  -3  -2
# [26]   2   3   5   7  11  13  17  19  23  29  31  37  41  43  47  53  59  61  67  71  73  79  83  89  97

http://diswww.mit.edu/bloom-picayune.mit.edu/perl/10138


Or if you take all the integers from 1 to x, the number which divide with no remainder should be 2: 1 and x

is.prime <- function(x)
  vapply(x, function(y) sum(y / 1:y == y %/% 1:y), integer(1L)) == 2L

(1:100)[is.prime(1:100)]
# [1]  2  3  5  7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

I knew the regex would be slowest, but it's still my favorite

is.prime <- function(x)
  vapply(x, function(y) sum(y / 1:y == y %/% 1:y), integer(1L)) == 2L

is.prime_regex <- function(x) {
  x <- abs(as.integer(x))
  !grepl('^1?$|^(11+?)\\1+$', strrep('1', x))
}

is.prime_Seily  <- function(n)
  vapply(n, function(y)
    y == 2L || all(y %% 2L:ceiling(sqrt(y)) != 0), logical(1L))

is.prime_flodel <- function(n)
  vapply(n, function(y)
    y == 2L || all(y %% 2L:max(2,floor(sqrt(y))) != 0), logical(1L))

x <- 1:1000

library('microbenchmark')
microbenchmark(
  is.prime(x),
  is.prime_regex(x),
  is.prime_Seily(x),
  is.prime_flodel(x),
  unit = 'relative'
)

# Unit: relative
#               expr       min        lq      mean    median        uq        max neval cld
#        is.prime(x)  8.593971  8.606353  8.805690  8.892905  9.724452 21.9886734   100  b 
#  is.prime_regex(x) 84.572928 86.200415 76.413036 86.895956 85.117796 25.7106323   100   c
#  is.prime_Seily(x)  1.000000  1.000000  1.000000  1.000000  1.000000  1.0000000   100 a  
# is.prime_flodel(x)  1.146212  1.147971  1.144839  1.146119  1.163302  0.9085948   100 a  



回答5:


I am going to provide you with 2 easy functions. The second one displays n-th prime number. EDIT* (typo)

PrimeNumber <- function(n){
#Eratosthenes 
#Return all prime numbers up to n (based on the sieve of Eratosthenes)
    if (n >= 2) {
      sieve <- seq(2, n)
      primes <- c()

      for (i in seq(2, n)) {
        if (any(sieve == i)) {
          primes <- c(primes, i)
          sieve <- c(sieve[(sieve %% i) != 0], i)
        }
      }
      return(primes)
    } else {
      stop("Input value of n should be at least 2.")
    }
}

testScript <- function(n){
i=3
v=c(2)
while (length(v)<=n-1){

      if (all((i%%v[v<ceiling(sqrt(i))])!=0)){ 
        v=c(v,i)
      }
    i=i+2;
  }
  return(v)
}



回答6:


Here is one more method to find prime number using simple concept

is.prime <- function(n){
 if (n == 2){  # finds the square root of number and assign to var 'i'
  print('number is prime')
 }
 else if (n > 2){
 i <- sqrt(n)   # finds the square root of number and assign to var 'i'
 i <- round(i, digits = 1) # if square root generates decimals, round it to one place
 vec <- c(2:i) #creating vector to load numbers from 2 to 'i'
 d <- n %% (vec) #dividing each number generated by vector by the input number 'n'
 if ( 0 %in% d){ # check to see if any of the result of division is 0
  print('number is not prime') #if any of the result of division is 0, number is not prime
 }
 else{ 
   print('number is prime')
 }
 }
}




is.prime(2)
[1] "number is prime"

is.prime(131) #calling the function with the desired number
[1] "number is prime"

is.prime(237)
[1] "number is not prime"



回答7:


This is the vectorized version with additional natural-number check:

is.prime <- Vectorize(function(n) ifelse(round(n) == n, 
                                  n == 2L || all(n %% 2L:max(2,floor(sqrt(n))) != 0), NA));

#> is.prime(c(1:10, 1.1))
# [1]  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE    NA



回答8:


    is.primeornot <- function(n)
    {
      count = 0
      for( i in 2:n)
      {

        if(n%%i == 0){count = count+1}

      }
      p = c(n)
      if(count > 1){
        print(paste(n,"is not a prime number"))}
      else{print("prime")}
    }



回答9:


Here is the most compact code I think:

is_prime <- function(n){
  ifelse(sum(n %% (1:n) == 0) > 2, FALSE, TRUE)
}

If you need to check whether each element of a vector of numbers is a prime number, you can do:

is_prime2 <- Vectorize(FUN = is_prime, vectorize.args = "n")

Now is_prime2() works with vectors.




回答10:


if(prime.num%%(2:(prime.num-1))!=0){

Change this statement to:

if(any(prime.num %% (2:(prime.num-1)) == rep(0,d-2))==TRUE){

and everything will work.




回答11:


Prime or not:

prime.or.not<-function(x){ifelse(0%in%(x%%(2:(x-1))),"not prime","prime")}


来源:https://stackoverflow.com/questions/19767408/prime-number-function-in-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!