I need to have a function where if a number entered is a prime number, it must round it up to the next prime number and if it is not to round it down to the previous prime number.
I have this code to identify whether it is a prime number:
prime <- function(x) {
if (x == 2) {
print(3)
} else if (any(x %% 2:(x-1) == 0)) {
FALSE
} else {
TRUE
}
}
I want to add a while loop to the true and false where if the function is false, it must minus one until it is true and if it is true, it must add one until it is true again but I am not sure how to do this.
Using your prime checker,
prime <- function(x) {
if (x == 2) {
print(3)
} else if (any(x %% 2:(x-1) == 0)) {
FALSE
} else {
TRUE
}
}
We build the new function, we first check if our number is a prime, if so, add 1 until we reach the next prime. If it is not a prime, we minus 1 until it is.
new <- function(x){
if (isTRUE(prime(x))){
x = x+1
while(prime(x) == FALSE){
x = x+1
}
return(x)
} else {
while(prime(x) == FALSE){
x = x-1
}
return(x)
}
}
we get
> new(7)
[1] 11
> new(10)
[1] 7
Related
I am working through practice problems for interviews and ran into a problem with an "if" statement that I do not know how to solve. The practice question is as follows:
Two sum. Given an array and a number N, return True if there are numbers A, B in the array such that A + B = N. Otherwise, return False.
Example:
[1, 2, 3, 4], 5 ⇒ True
[3, 4, 6], 6 ⇒ False
My code (below) returns the following error: Error in if (i + A[j] == N) { : missing value where TRUE/FALSE needed
fun = function(A,N) {
flag = FALSE
for (i in A) {
for (j in i:length(A)) {
if (i + A[j] == N) {
flag = TRUE
}
}
}
return(flag)
}
fun(as.integer(c(3, 4, 6)),6)
The problem in your code is your second for loop should be 1:length(A) not i:length(A).
fun <- function(A, N){
flag = FALSE
for (i in A) {
for (j in 1:length(A)) {
if (i + A[j] == N) {
flag = TRUE
}
}
}
return(flag)
}
fun(as.integer(c(3, 4, 6)), 6)
[1] TRUE
When i equals 4 and length(A) is fixed at 3 your posted code was sequencing 4:3. j will take on a value of 4 and then when you try to index A[4] you will get NA.
Update
To avoid double counting an element with your code you could do this:
fun <- function(A, N){
flag = FALSE
for (i in A) {
for (j in A[A != i]) { # select elements of A that aren't equal to i
if (i + j == N) {
flag = TRUE
}
}
}
return(flag)
}
Though this isn't super efficient because it will double check some pairs twice.
A vectorized solution without loops:
sumN <- function(A,N){
any(colSums(combn(A,2))==N)
}
sumN(c(1,2,3,4),5)
[1] TRUE
sumN(c(3,4,6),6)
[1] FALSE
I am trying to create functions that evaluates numbers and adds them to a category dependent on set criteria.
I wrote a "stupid" function with a lot of repetitions and lines, that can solve the job in a simple case:
# Findgroup (Everything manually typed out)
# Purpose of function:
#If 1 or 2: output A
#If 3 or 4: output B
#If 5 or 6: output random A/B (bonus if this can be balanced equally over the dataset)
# Else output "error"
findGroup <- function(x){ if (x == 1) {
"A"
} else if (x == 2) {
"A"
} else if (x == 3) {
"B"
} else if (x == 4) {
"B"
}else if (x == 5) {
sample(c("sA","sB"),1)
}else if (x == 6) {
sample(c("sA","sB"),1)
} else {
"Error"
}}
# Brief test: All matches expectations
findGroup(1) # Returns A
findGroup(3) # Returns B
findGroup(5) # Samples
findGroup(7) # Returns Error
This is okay, if I had to evaluate a few numbers. But what should I do if the list of numbers is much more elaborate? I tried to write a function that solves this in fewer lines, but the result does not work:
# Findgroup new
# Purpose of function:
#If 2:8: output A
#If 10:16: output B
#If 1,9: output random A/B (bonus if this can be balanced equally)
findGroupNew <- function(x){ if (x == 2|3|4|5|6|7|8) {
"A"
} else if (x == 10|11|12|13|14|15|16) {
"B"
} else if (x == 1||9) {
sample(c("sA","sB"),1)
} else {
"Error"
}}
# Brief test: All return A!!!
findGroupNew(1) # Should sample
findGroupNew(3) # Should Return A
findGroupNew(11) # Should Return B
findGroupNew(17) # Should Return Error
It may be a stupid mistake such as not having used the right sign for OR, but having tried solutions such as using || and & has not been successful.
I hope there is a quick fix to this issue and will appreciate your feedback.
Use %in% to check for multiple values.
findGroupNew <- function(x) {
if (x %in% 2:6) {
return("A")
} else if (x %in% 10:16) {
return("B")
} else if (x %in% c(1, 9)) {
return(sample(c("sA","sB"),1))
} else {
return("Error")
}
}
findGroupNew(1)
#[1] "sB"
findGroupNew(3)
#[1] "A"
findGroupNew(11)
#[1] "B"
findGroupNew(7)
#[1] "Error"
i've been trying for a while now to write a function that has two arguments. The one an integer = n and the other a logical argument. How would i write a function that would return either the first n prime numbers in a vector if the logical argument is true or the n th prime number if the logical argument is false?
This is as far as i have gotten.
getprime <- function(n=0 , all=TRUE) {
if (n<=0) {
print("Not a valid number")
} else if (n>0) {
for (primen in 1:n) {
while (n %% 2:(n-1) == 0) {
n=n+1
print(n)
}
}
}
print(n)
}
The results that have to be displayed are shown below.
> genprime(7, all=TRUE)
[1] 2 3 5 7 11 13 17
> genprime(7, all=FALSE)
[1] 17
You could write a recursive function (a function that calls itself). In addition to the two arguments n and all, it would also take a counter i and a (empty) vector of prime numbers primes.
As long as the number of prime numbers found is less than n, the function calls itself and with each time it calls itself, it would increase the counter variable i. If i is a prime number, it gets added to the primes vector.
get_prime <- function(n, all = TRUE, i = 1, primes = c()){
if ( n <= 0) {
stop("Not a valid number")
}
if (length(primes) < n) {
if (i == 2L || all(i %% 2L:ceiling(sqrt(i)) != 0)) {
get_prime(n, all = all, i = i + 1, primes = c(primes, i))
} else {
get_prime(n, all = all, i = i + 1, primes = primes)
}
} else {
if (all) {
return(primes)
} else {
return(tail(primes, 1))
}
}
}
The results are:
get_prime(7, TRUE)
[1] 2 3 5 7 11 13 17
get_prime(7, FALSE)
[1] 17
While working on some problem i came across a situation in which i wanted to know if a function was executed when called upon. To do so i put a print statement in the function.
abc = function(x)
if(x > 0) {
return(x)
print("Go")
} else {
return(0)
print("Run")
}
y = abc(3)
y
# [1] 3
Why print statement is not executed while calling abc()?
That is because you are returning before printing. Change the sequence of those two statements and it should print
abc = function(x) {
if(x > 0) {
print("Go")
return(x)
} else {
print("Run")
return(0)
}
}
abc(3)
#[1] "Go"
#[1] 3
abc(-3)
#[1] "Run"
#[1] 0
i <- 2
j <- 0
for (i in 2:1000) {
if(return.prime(i)){j = j + 1}
i = i + 1
}
I want to check how many prime numbers there are in 1 to 1000 using my own function return.prime which returns TRUE when the number input is a prime and FALSE when the number input is not prime. The return.prime function is the function below and it is correct.
return.prime <- function(d){
if(d ==1 ){print(FALSE)}
if (d == 2){
print(TRUE)
}
if(d !=2 && d!=1){
if(any(d %% (2:(d-1)) == rep(0,d-2))==TRUE){
print(FALSE)}
else
print(TRUE)
}
}
The problem is when I run my program it says:
[1] TRUE
Error in if (return.prime(i)) { : argument is of length zero
I do not know what causes the length zero.
R doesn't work that way. You're just having the function print the word "TRUE" or "FALSE". Instead, you need to ?return TRUE or FALSE. Consider:
return.prime <- function(d){
if(d==1){ return(FALSE) }
if(d==2){ return(TRUE) }
if(d !=2 && d!=1){
if(any(d %% (2:(d-1)) == rep(0,d-2))==TRUE){
return(FALSE)
} else{
return(TRUE)
}
}
}
i <- 2
j <- 0
for (i in 2:1000) {
if(return.prime(i)){j = j + 1}
i = i + 1
}
j # [1] 168