与えられた整数が素数であるかどうかをテストする関数を作成しようとしています、私は以下を使ってみました:
_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")
}}}
_
理由はわかりませんが、これは機能しません。私は与えられた数が余りのないこの数までの整数のいずれかで除算できるかどうかを確認しています。それができない場合、数は素数です。
私が見つけた別の解決策は:
_tpn <- function(pn){
if(sum(pn/1:pn==pn%/%1:pn)==2)
print("prime")
}
_
これは機能します。ただし、sum(pn/1:pn == pn%/%1:pn) == 2
が実際にテストしているものを理解することはできません。
除算_a / b
_の結果が整数除算_a %/% b
_の結果と等しい場合、数値a
は数値b
で割り切れます。任意の整数pn
は、少なくとも2つの数値(_1
_およびpn
)で除算できます。素数は、これらの2つで除算できるだけのものです。コードを分解する:
pn / 1:pn
_は、_1
_、_2
_、...、pn
による除算の結果です。pn %/% 1:pn
_は、_1
_、_2
_、...、pn
による整数除算の結果です。sum(pn / 1:pn == pn %/% 1:pn)
は、これらのうちどれだけ等しいか、つまりpn
の整数除数の数です。この数が_2
_の場合、素数があります。コードの何が問題でしたか:if
は、何かがTRUE
またはFALSE
であるかどうかをテストする必要がありますが、ベクトル全体を渡しています。また、あなたの論理は間違っていました。それはそうだったはずです:
_is.prime <- function(num) {
if (num == 2) {
TRUE
} else if (any(num %% 2:(num-1) == 0)) {
FALSE
} else {
TRUE
}
}
_
そして、論理値を返すことに決めたら、コードを大幅に短くすることができます。
_is.prime <- function(n) n == 2L || all(n %% 2L:max(2,floor(sqrt(n))) != 0)
_
(すべての数値をチェックしないことについての@Carlのコメントが組み込まれています。)
is.prime
コード例。しかし、これで3は素数ではありません; o)
改善されたバージョンでは、床の操作ではなく天井を使用します。
is.prime <- function(n) n == 2L || all(n %% 2L:ceiling(sqrt(n)) != 0)
ベスト!
matlab パッケージのisprime()
関数を使用することもできます。これは、ベクトル引数でも機能します。
library(matlab)
as.logical(isprime(7))
as.logical(isprime(42))
#> as.logical(isprime(7))
#[1] TRUE
#> as.logical(isprime(42))
#[1] FALSE
素数を見つけるための正規表現
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
または、1からx
までのすべての整数を取得する場合、剰余なしで割る数は2である必要があります:1と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
正規表現が最も遅いことは知っていましたが、それでも私のお気に入りです
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
単純な概念を使用して素数を見つけるもう1つの方法を次に示します
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"
素数かどうか:
prime.or.not<-function(x){ifelse(0%in%(x%%(2:(x-1))),"not prime","prime")}
2つの簡単な機能を提供します。 2番目はn-番目の素数を表示します。編集*(タイプミス)
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)
}
if(prime.num%%(2:(prime.num-1))!=0){
このステートメントを次のように変更します。
if(any(prime.num %% (2:(prime.num-1)) == rep(0,d-2))==TRUE){
そして、すべてが機能します。
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")}
}
これは、追加の自然数チェックを備えたベクトル化バージョンです。
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_prime <- function(n){
ifelse(sum(n %% (1:n) == 0) > 2, FALSE, TRUE)
}
_
数値のベクトルの各要素が素数かどうかを確認する必要がある場合は、次のようにできます。
_is_prime2 <- Vectorize(FUN = is_prime, vectorize.args = "n")
_
現在、is_prime2()
はベクトルで機能します。