Skip to content

Instantly share code, notes, and snippets.

@MyKo101
Created November 9, 2022 20:25
Show Gist options
  • Select an option

  • Save MyKo101/52a2c3299237c5bd8db9fc4c8246a782 to your computer and use it in GitHub Desktop.

Select an option

Save MyKo101/52a2c3299237c5bd8db9fc4c8246a782 to your computer and use it in GitHub Desktop.
Function to calculate whether a vector is prime.
# This function will calculate whether a vector is prime. It is not completely efficient, but it's not too bad
isPrime <- function(n){
# Check inputs are integers, and coerce
if(any(n %% 1 >0)) stop("Input must be all integers")
n2 <- as.integer(n)
# Create default output
out <- rep(NA,length(n2))
# Check for already discovered primes & return early if possible
out[n2 %in% p_list] <- TRUE
if(all(!is.na(out))) return(out)
# Check for already discovered non-Primes & return early if possible
out[is.na(out) & n2 <= MaxChecked] <- FALSE
if(all(!is.na(out))) return(out)
# Check for divisibility by current prime list
n3 <- n2[is.na(out)]
# Create a divisibility matrix, and sum for any non-zero modulos
is_divisible <- rowSums(
!(
matrix(rep(n3,length(p_list)),nrow=length(n3)) %%
matrix(rep(p_list,each=length(n3)),nrow=length(n3))
)
) > 0
# Any that are divisble by a previously found Prime, are non-Prime
out[is.na(out)][is_divisible] <- FALSE
if(all(!is.na(out))) return(out)
# Create a sequence from the previous maximum to the new current maximum
NewMax <- max(n2)+1
new_checks <- seq(MaxChecked+1,NewMax)
# Check values in this new sequence, adding new primes when found
for(c_new in new_checks){
if(all(c_new %% p_list)){
# Current checked value is prime, add to list and output
out[n2 == c_new] <- TRUE
out[is.na(out) & (n2 %% c_new == 0)] <- FALSE
p_list <- c(p_list,c_new)
# If all results have now been found, break early
if(all(!is.na(out))) break
}
}
# Re-cache the variables
e <- parent.env(environment())
e$MaxChecked <- c_new
e$p_list <- p_list
# Any that aren't marked as TRUE or FALSE must be non-Prime
out[is.na(out)] <- FALSE
return(out)
}
# Create a cache in the function's environment
environment(isPrime) <- list2env(list(
# The L here forces the values to be integers (more efficient than numeric)
p_list = c(2L,3L,5L),
MaxChecked = 5L
))
# First run is slow!
start_timer <- Sys.time()
isPrime(300007)
print(Sys.time() - start_timer)
# Second run is fast because of caching
start_timer <- Sys.time()
isPrime(300007)
print(Sys.time() - start_timer)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment