Explanation of a single line of code for prime numbers - r

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

Related

If statement condition error missing value in two sum problem?

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

Couldn't calculate prime numbers within a range

for (i in 2:100 )
{
count <- 0
for (j in i )
if( (i %% j ) == 0 )
count <- count + 1
if(count == 2 )
print(i)
}
I am trying to print print prime numbers in R. Could any one help me to resolve
Let us look at your code and show what went wrong. It's the inner loop that did not loop at all:
for (i in 2:100 )
{
count <- 0
for (j in 1:i ) # you forgot to provide a vector here
if( i %% j == 0 )
count <- count + 1
if(count == 2)
print(i)
}
The answer above tries to optimise the code some more and is a more efficient solution. For example does it only test odd numbers because even ones clearly aren't prime numbers.
The below code creates the function prime_numbers which returns prime numbers up to an inputted number.
prime_numbers <- function(n) {
if (n >= 2) {
x = seq(2, n)
prime_nums = c()
for (i in seq(2, n)) {
if (any(x == i)) {
prime_nums = c(prime_nums, i)
x = c(x[(x %% i) != 0], i)
}
}
return(prime_nums)
}
else {
stop("Input number should be at least 2.")
}
}
## return the answer to your question
prime_numbers(100)
If you wanted the range 3:100, after running the above code you could run something like this:
a<-prime_numbers(100)
a[a>3]
I hope this helps!

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

R - prime factorization

Can you please help me with this excercise? I do not know much about math algorithms and even less about R language. Thank you.
A program reads an integer from the user. If the value entered by the user is less than 2 then program should display an error. Otherwise program should display the prime numbers that can be multiplied together to compute n, with one factor appearing on each line. For example:
The prime factors of 72 are: 2, 2, 2, 3, 3
I have this code in C that calculates the prime numbers
#include <stdio.h>
int main()
{
int i, j, num, isPrime;
/* Input a number from user */
printf("Enter any number to print Prime factors: ");
scanf("%d", &num);
printf("All Prime Factors of %d are: \n", num);
/* Find all Prime factors */
for(i=2; i<=num; i++)
{
/* Check 'i' for factor of num */
if(num%i==0)
{
/* Check 'i' for Prime */
isPrime = 1;
for(j=2; j<=i/2; j++)
{
if(i%j==0)
{
isPrime = 0;
break;
}
}
/* If 'i' is Prime number and factor of num */
if(isPrime==1)
{
printf("%d, ", i);
}
}
}
return 0;
}
But output is only this
All Prime Factors of 72 are: 2, 3
Instead of this:
2, 2, 2, 3, 3
I also do not have a clue how to translate this to R.
Using Recursion
prime_factors <- function(x, i=2, factors = NULL){
if(x<i) factors
else if(! x %% i) prime_factors(x/i, i, c(factors, i))
else prime_factors(x, i+1, factors)
}
prime_factors(72)
[1] 2 2 2 3 3
Using While loop:
prime_factors_Loop <- function(x){
factors = c()
i = 2
while(x >= i){
if(! x %% i) {
factors <- c(factors, i)
x <- x/i
i <- i - 1
}
i <- i + 1
}
factors
}
prime_factors_Loop(72)
[1] 2 2 2 3 3
Using packages
First, install the CRAN package numbers on your computer.
install.packages("numbers")
Now, load the package in your R session and get the prime factors.
library(numbers)
primeFactors(600851475143)
This is what I wrote some time back, it may require some improvement though. Updated it according to your requirement.
get_prime_factors <- function() {
num <- as.numeric(readline(prompt="Enter number: " ))
n <- num
if (n > 2) {
numvec <- numeric()
while(n %% 2 == 0){
numvec = c(numvec, 2)
n = n/2
}
i = 3
while(n != 1) {
while(n %% i == 0) {
numvec = c(numvec, i)
n = n/i
}
i = i + 2
}
sprintf("All Prime Factors of %d are:%s", num, paste0(sort(numvec), collapse = ","))
}
else {
stop("Try a bigger number")
}
}
Running with few sample examples :
get_prime_factors()
Enter number: 100
#[1] "All Prime Factors of 100 are : 2,2,5,5"
get_prime_factors()
Enter number: 72
#[1] "All Prime Factors of 72 are : 2,2,2,3,3"
get_prime_factors()
Enter number: -9
Error in get_prime_factors() : Try a bigger number

implement matrix determinant in R

I was asked to implement function that calculates n-dimensional matrix determinant using Laplace expansion. This involves recursion. I developed this:
minor<-function(A,i,j) {
return(A[c(1:(i-1),(i+1):dim(A)[1]),c(1:(j-1),(j+1):dim(A)[2])])
}
determinantRec<-function(X,k) {
if (dim(X)[1] == 1 && dim(X)[2] == 1) return(X[1][1])
else {
s = 0
for (i in 1:dim(X)[2]) {
s = s + X[k][i]*(-1)^(k+i)*determinantRec(minor(X,k,i),k)
}
return(s)
}
}
where k in determinantRec(X,k) function indicates which row I want to use Laplace expansion along of.
My problem is when I run determinantRec(matrix(c(1,2,3,4),nrow = 2,ncol = 2),1) this error appears:
C stack usage 7970628 is too close to the limit
What is wrong with my code?
#julia, there is one simple type in your code. Just remove the '*' at the end of the definition of 's'. And don't indent the recursion.
determinantRek<-function(X,k) {
if (dim(X)[1] == 1 && dim(X)[2] == 1)
return(X[1,1])
if (dim(X)[1] == 2 && dim(X)[2] == 2)
return(X[1,1]*X[2,2]-X[1,2]*X[2,1])
else
s = 0
for (i in 1:dim(X)[2]) {
s = s + X[k,i]*(-1)^(k+i)
determinantRek(X[-k,-i],k)
}
return(s)
}
I did this way and works just fine, although it is super slow, compared to the det function in base R
laplace_expansion <- function(mat){
det1 <- function(mat){
mat[1]*mat[4]-mat[2]*mat[3]
}
determinant <- 0
for(j in 1:ncol(mat)){
mat1 <- mat[-1,-j]
if(nrow(mat1) == 2){
determinant <- determinant+mat[1,j]*(-1)^(1+j)*det1(mat1)
}else{
val <- mat[1,j]*(-1)^(1+j)
if(val != 0){
determinant <- determinant+val*laplace_expansion(mat1)
}
}
}
return(determinant)
}
This is my approach, I think it's cleaner.
deter <- function(X) {
stopifnot(is.matrix(X))
stopifnot(identical(ncol(X), nrow(X)))
if (all(dim(X) == c(1, 1))) return(as.numeric(X))
i <- 1:nrow(X)
out <- purrr::map_dbl(i, function(i){
X[i, 1] * (-1)^(i + 1) * deter(X[-i, -1, drop = FALSE])
})
return(sum(out))
}
Thank you #ArtemSokolov and #MrFlick for pointing the problem cause, it was it. I also discovered that this code does not calculate properly the determinant of 2x2 matrix. After all it looks like that:
determinantRek<-function(X,k) {
if (dim(X)[1] == 1 && dim(X)[2] == 1)
return(X[1,1])
if (dim(X)[1] == 2 && dim(X)[2] == 2)
return(X[1,1]*X[2,2]-X[1,2]*X[2,1])
else
s = 0
for (i in 1:dim(X)[2]) {
s = s + X[k,i]*(-1)^(k+i)*
determinantRek(X[-k,-i],k)
}
return(s)
}
Debuging with browser() was also helpful :)

Resources