web-dev-qa-db-fra.com

Fonction du nombre premier dans R

J'essaie de créer une fonction pour tester si un entier donné est un nombre premier, j'ai essayé d'utiliser les éléments suivants:

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")

}}}

Cela ne fonctionne pas, bien que je ne comprenne pas pourquoi. Je vérifie si le nombre donné peut être divisé par l'un des nombres entiers jusqu'à ce nombre sans reste. S'il ne peut pas, alors le nombre est premier.

Une autre solution que j'ai trouvée était:

tpn <- function(pn){

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

}

Cela marche. Bien que je ne sache pas exactement ce que sum(pn/1:pn == pn%/%1:pn) == 2 est en train de tester.

10
user2952367

Un nombre a est divisible par un nombre b si le résultat de la division a / b est égal au résultat de la division entière a %/% b. Tout nombre entier pn peut être divisé par au moins deux nombres: 1 et pn. Les nombres premiers sont ceux qui ne peuvent être divisés que par ces deux. Sortir le code:

  1. pn / 1:pn sont les résultats des divisions par 1, 2, ..., pn
  2. pn %/% 1:pn sont les résultats des divisions entières par 1, 2, ..., pn
  3. sum(pn / 1:pn == pn %/% 1:pn) sont le nombre de ceux-ci qui sont égaux, c'est-à-dire le nombre de diviseurs entiers de pn. Si ce nombre est 2, vous avez un nombre premier.

Qu'est-ce qui n'allait pas dans votre code: if doit tester si quelque chose est TRUE ou FALSE mais que vous lui transmettiez un vecteur entier. En outre, votre logique était fausse. Cela aurait dû être:

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

Et une fois que vous avez décidé de renvoyer une logique, vous pouvez raccourcir votre code:

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

(qui intègre le commentaire de @ Carl sur le fait de ne pas vérifier tous les nombres.)

20
flodel

Je viens d'essayer l'exemple de code is.prime. Mais avec cela 3 n'est pas premier; o)

La version améliorée utilise le plafond au lieu du fonctionnement au sol.

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

Meilleur!

7
Seily

Vous pouvez également utiliser la fonction isprime() dans le package matlab . Cela fonctionne aussi avec les arguments vectoriels:

library(matlab)

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

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

Une expression régulière pour trouver des nombres premiers

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


Ou si vous prenez tous les entiers de 1 à x, le nombre qui divise sans reste devrait être 2: 1 et 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

Je savais que la regex serait la plus lente, mais c'est toujours ma préférée

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  
3
rawr

Voici une autre méthode pour trouver un nombre premier en utilisant un concept simple

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"
1
Sugand Anand

Je vais vous fournir 2 fonctions faciles. Le second affiche n - ème nombre premier. EDIT * (faute de frappe)

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)
}
1
MathGainz

prime ou pas:

prime.ou.pas <fonction (x) {ifelse (0% en% (x %% (2: (x-1))), "pas de prime", "prime")}

0
A Chatterjee
    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")}
    }
0
neeraj Guntupalli

Ceci est la version vectorisée avec vérification supplémentaire du nombre naturel:

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
0
Yuri

Voici le code le plus compact je pense:

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

Si vous devez vérifier si chaque élément d'un vecteur de nombres est un nombre premier, vous pouvez faire:

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

Maintenant, is_prime2() fonctionne avec des vecteurs.

0
SavedByJESUS