R - prime factorization - r

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

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!

Problems with an implementation of Heapsort algorithm in R

I would like to create my own Heapsort algorithm in R.
That is my code
heapify <- function(array, n, i)
{
parent <- i
leftChild <- 2 * i + 1
rightChild <- 2 * i + 2
if ((leftChild < n) & (array[parent] < array[leftChild]))
{
parent = leftChild
}
if ((rightChild < n) & (array[parent] < array[rightChild]))
{
parent = rightChild
}
if (parent != i)
{
array = replace(array, c(i, parent), c(array[parent], array[i]))
heapify(array, n, parent)
}
}
heapSort <- function(array)
{
n <- length(array)
for (i in (n+1):1)
{
heapify(array, n, i)
}
for (i in n:1)
{
array = replace(array, c(i, 0), c(array[0], array[i]))
heapify(array, i, 1)
}
print(array)
}
However that implementation seems to be incorrect. That's an example of an input and output.
array <- c(5, 14, 3, 70, 64)
heapSort(array)
Output: [1] 5 14 3 70 64
I have spent quite a while and I have no idea where the problem is. I would appreciate any hints or tips.
My guess is that you were trying to convert the algorithm posted on GeeksforGeeks where they implement this in many zero based languages. This is one of the sources of your problem (R starts indexing at 1 instead of 0).
Base Zero Indexing Issues:
Example 1:
## We also need to swap these indices
array = replace(array, c(i, 0), c(array[0], array[i]))
heapify(array, i, 1)
Should be:
array <- replace(array, c(i, 1), array[c(1, i)])
array <- heapify(array, i, 1)
Example 2:
leftChild <- 2 * i + 1
rightChild <- 2 * i + 2
Should be:
leftChild <- 2 * (i - 1) + 1
rightChild <- 2 * (i - 1) + 2
Pass By Reference Assumption
In R, you cannot pass an object by reference (see this question and answers Can you pass-by-reference in R?). This means that when we call a recursive function we must assign it and the recursive function must return something.
In heapify we must return array. Also every call to heapify we must assign array to the output.
Here is the amended code:
heapify <- function(array, n, i)
{
parent <- i
leftChild <- 2 * (i - 1) + 1
rightChild <- 2 * (i - 1) + 2
if ((leftChild < n) & (array[parent] < array[leftChild]))
{
parent <- leftChild
}
if ((rightChild < n) & (array[parent] < array[rightChild]))
{
parent <- rightChild
}
if (parent != i) {
array <- replace(array, c(i, parent), array[c(parent, i)])
array <- heapify(array, n, parent)
}
array
}
heapSort <- function(array)
{
n <- length(array)
for (i in floor(n / 2):1) {
array <- heapify(array, n, i)
}
for (i in n:1) {
array <- replace(array, c(i, 1), array[c(1, i)])
array <- heapify(array, i, 1)
}
array
}
Here are some tests (note this algorithm is extremely inefficient in R.. do not try on vectors much larger than below):
array <- c(5, 14, 3, 70, 64)
heapSort(array)
[1] 3 5 14 64 70
set.seed(11)
largerExample <- sample(1e3)
head(largerExample)
[1] 278 1 510 15 65 951
identical(heapSort(largerExample), 1:1e3)
[1] TRUE

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

Resources