问题
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:
pn / 1:pn
are the results of the divisions by1
,2
, ...,pn
pn %/% 1:pn
are the results of the integer divisions by1
,2
, ...,pn
sum(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.)
回答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