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.
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:
pn / 1:pnare the results of the divisions by1,2, ...,pnpn %/% 1:pnare the results of the integer divisions by1,2, ...,pnsum(pn / 1:pn == pn %/% 1:pn)are how many of these are equal, i.e., the number of integer divisors ofpn. If this number is2, 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.)
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!
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
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
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)
}
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"
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
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")}
}
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.
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.
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