Функция правого числа в R

Я пытаюсь создать функцию для проверки, является ли заданное целое число простым числом, я попытался использовать следующее:

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 действительно тестирует.

Ответ 1

Число a делится на число b, если результат деления a / b равен результату целочисленного деления a %/% b. Любое целое число pn можно разделить по крайней мере на два числа: 1 и pn. Правые числа - это те, которые могут быть разделены только этими двумя. Вывод кода:

  • 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 о ​​том, чтобы не проверять все числа.)

Ответ 2

Я просто попробовал пример кода is.prime. Но с этим 3 не является простым, o)

В улучшенной версии вместо потолка используется потолок.

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

Best!

Ответ 3

Вы также можете использовать функцию isprime() в пакете matlab. Он также работает с векторными аргументами:

library(matlab)

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

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

Ответ 4

Регулярное выражение для нахождения простых чисел

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  

Ответ 5

Я собираюсь предоставить вам 2 простых функции. Второй показывает n-е простое число. EDIT * (опечатка)

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

Вот еще один способ найти простое число, используя простую концепцию

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

Это векторизованная версия с дополнительной проверкой натурального числа:

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

Вот самый компактный код, который я думаю:

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

Если вам нужно проверить, является ли каждый элемент вектора чисел простым числом, вы можете сделать:

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

Теперь is_prime2() работает с векторами.

Ответ 10

премьер или нет:

prime.or.not <-function (x) {ifelse (0% в% (x %% (2: (x-1))), "не простое", "простое")}

Ответ 11

1) Любое число n может иметь только один простой множитель больше, чем sqrt (n) 2) Все простые числа больше 3 могут быть записаны в виде 6k+ / -1

    is.prime <- function(n){
        x1<- (if (n==1){return(FALSE)}
                else if(n<4){return(TRUE)}
                else if(n%%2==0){return(FALSE)}
                else if(n<9){return(TRUE)}
                else if(n%%3==0){return(FALSE)}
                else {
                      r=floor(n^.5)
                      f=5
                      while(f<=r){
                      if(n%%f==0){return(FALSE);break}
                      else if(n%%(f+2)==0){return(FALSE);break}
                      f=f+6
                      }
                  })  
          if(is.null(x1)){return(TRUE)}  
      }