If statement condition error missing value in two sum problem? - r

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

Related

How do I vectorize this is_prime function in R?

I have created this function that takes number and return TRUE or FALSE depending whether the number is prime or not.
is.prime <- function(num) {
if (num == 2) {
TRUE
} else if (any(num %% 2:(num-1) == 0)) {
FALSE
} else {
TRUE
}
}
However, this function takes only one value, for example this works fine:
> is_prime(17)
[1] TRUE
If I plug in a vector, I want to see TRUE or FALSE for each element. For example,
> is_prime(c(17,5,10,22,109,55))
[1] TRUE
Warning messages:
1: In if (x == 1) { :
the condition has length > 1 and only the first element will be used
2: In 2:(floor(x/2)) :
numerical expression has 6 elements: only the first used
3: In x%%2:(floor(x/2)) :
longer object length is not a multiple of shorter object length
This is evaluated for the first element, but I would want to see
TRUE TRUE FALSE FALSE TRUE FALSE
for the vector
is_prime(c(17,5,10,22,109,55))
How would I modify the function to vectorize using the same algorithm?
Half Vectorized
It is possible to vectorize some of the function by dealing with even numbers (and a few other numbers) in a vectorized fashion. The rest is taken care of using vapply.
helper <- function(x) {
for (k in seq(3, round(sqrt(x)) + 1, 2)) {
if (x %% k == 0)
return(FALSE)
}
return(TRUE)
}
is.prime <- function(v) {
out <- rep(TRUE, length(v))
out[v %% 2 == 0 | v %in% c(1)] <- FALSE
out[v %in% c(2, 3, 5)] <- TRUE
indices <- which(v > 5 && v == FALSE)
out[indices] <- vapply(v[indices], helper, logical(1))
return(out)
}
is.prime(c(17,5,10,22,109,55))
# [1] TRUE TRUE FALSE FALSE TRUE FALSE
Full Vectorized
If performance is at stake, you might consider using `Rcpp`:
c++ file
#include <Rcpp.h>
#include <math.h>
using namespace Rcpp;
bool is_prime(int n) {
if ((n == 2) || (n == 3) || (n == 5)) {
return true;
}
if ((n % 2 == 0) || (n == 1)) {
return false;
}
int i = 3;
while (i < round(sqrt(n)) + 1) {
if (n % i == 0) {
return false;
}
i += 2;
}
return true;
}
// [[Rcpp::export]]
LogicalVector is_prime(IntegerVector v) {
int n = v.length();
LogicalVector out = LogicalVector(n);
for (int i = 0; i < n; i++) {
out[i] = is_prime(v[i]);
}
return out;
}
R File
library(Rcpp)
sourceCpp('prime_fun.cpp') # if cpp file in same dir
is_prime(c(17,5,10,22,109,55))
# [1] TRUE TRUE FALSE FALSE TRUE FALSE
Technically, you cannot vectorize the function but you can use methods to apply is.prime function to vectors.
For example, use sapply :
sapply(c(17,5,10,22,109,55), is.prime)
#[1] TRUE TRUE FALSE FALSE TRUE FALSE
Or use Vectorize which is a wrapper around mapply :
vec.is.prime <- Vectorize(is.prime)
vec.is.prime(c(17,5,10,22,109,55))
#[1] TRUE TRUE FALSE FALSE TRUE FALSE
R is an inherently vectorized language, you just have to not break that when you write functions...
is.prime <- function(num){
res<-rep(TRUE, length(num))
for(i in 2:(max(num)-1) ){
res[(i < num) & ((num %% i) == 0) ] <- FALSE
}
return(res)
}
x<-c(2, 5, 17, 109, 10, 22, 55, 93)
print("Primes:")
print(x[ is.prime(x) ] )
Output:
> source('~/.active-rstudio-document')
[1] "Primes:"
[1] 2 5 17 109

Explanation of a single line of code for prime numbers

Hi i just need some help understanding this line of code from a function to get prime numbers (see below for the whole function):
if (i == 2L || all(i %% 2L:ceiling(sqrt(i)) != 0))
What does i == 2L do as well as ceiling(sqrt(i)). This function basically just generates a vector of prime numbers or just returns the last prime number in the vector. I don't quite understand what those 2 sections are used for.
Normally i would just check for a prime number like this all(i %% 2:(i-1) !=0) So why are those two elements changed in the code?
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))
}
}
}
Imagine you had to check if q=1,000,001 was a prime number.
The simplest way to do this is to check if any integer in [2, 1000000] is a factor of q.
Suppose a factor, f, of q does exist and it is not in [2, ceiling(sqrt(q))].
So f > ceiling(sqrt(q)) and q/f <= q/sqrt(q) = sqrt(q)
So whatever q/f is, it lies in [2, ceiling(sqrt(q))].
That's why you only need to check up to ceiling(sqrt(q))

How to create a loop that returns the first N prime numbers in a vector?

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

Question regarding R code to do with rounding prime numbers

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

Loop returns error: 'argument is of length zero'

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

Resources