2

I'm working on problem 5 of Project Euler. I'm trying to convert another user's Python code into R, but the output is different.

The Python script's output is 232792560, where's the R script's output is 1964187225

Where is the error?

Python code:

def is_prime(number):
    for n in range(2, number):
        if number % n != 0:
            n += 1
        else:
            return False
    return True


def smallest_multiple(num):
    exp = 1
    result = 1
    for i in range(2, num):
        if is_prime(i):
            while True:
                if i**exp > num:
                    result *= i**(exp-1)
                    break
                exp += 1
            exp = 1
    return result

print(smallest_multiple(20))

R code:

is_prime <- function(num) {
  for (n in seq(2, num)) {
    if (num %% n != 0) {
      n <- n + 1
    } else {
      return(FALSE)
    }
    return(TRUE)
  }
}

lcm <- function(num) {
  exp <- 1
  result <- 1
  for (i in seq(2, num)) {
    if (is_prime(i)) {
      while (TRUE) {
        if (i ^ exp > num) {
          result <- result * i ^ (exp - 1)
          break
        }
        exp <- exp + 1
      }
      exp <- 1
    }
  }
  return(result)
}
lcm(20)
gmds
  • 19,325
  • 4
  • 32
  • 58
juby
  • 132
  • 1
  • 5
  • Check [here](https://stackoverflow.com/questions/8024911/project-euler-5-in-python-how-can-i-optimize-my-solution) and [here](https://www.r-bloggers.com/project-euler-problem-5/). It is how the R interpreter is different from python. It is pretty intuitive – ASHu2 May 18 '19 at 04:25
  • As per your R code, 2 is not prime. – Anubhav Singh May 18 '19 at 04:36
  • seq(2, num) runs from 2 to num while range(2, num) runs from 2 to (num-1) – Anubhav Singh May 18 '19 at 04:51

1 Answers1

1

There are two problems with your solution.

First, seq in R includes the endpoint; range in Python does not. Furthermore, range(2, 1) in Python is an empty range, whereas seq(2, 1) in R produces the result 2 1. Therefore, it is necessary to modify your R is_prime function to check explicitly if the input is 2.

Second, your is_prime function in R has return (TRUE) in the for loop, when it should be outside (a number is prime only if it is not divisible by any number less than it).

This will work:

is_prime <- function(num) {
  if (num == 2){
    return(TRUE)
  }
  for (n in seq(2, num - 1)) {
    if (num %% n == 0) {
      return(FALSE)
    } 
  }
  return(TRUE)
}

lcm <- function(num) {
  exp <- 1
  result <- 1
  for (i in seq(2, num - 1)) {
    if (is_prime(i)) {
      while (TRUE) {
        if (i ^ exp > num) {
          result <- result * i ^ (exp - 1)
          break
        }
        exp <- exp + 1
      }
      exp <- 1
    }
  }
  return(result)
}
lcm(20)

Output:

232792560

There are other weird things about your code; for example, you do not need to add 1 to n manually, you only have to check up to the square root of n, and even numbers are immediately out. Nevertheless, these are more questions of efficiency than correctness.

gmds
  • 19,325
  • 4
  • 32
  • 58