-1

I'm learning an swift and I've written two functions and have tried them on their own they both work well. However when I try to call one function within another one I can't seem to get the desired out-put that I seek.

The task at hand is that one function should print Prime numbers whilst the other is to calculate and check if the number is prime. I am supposed to call the check if number is prime from the print Prime numbers function.

below is my code:

This function calculates whether or not the X:Int is a prime number. It's set to a boolean because I'm supposed to print "true" or "false" in the function below it.

func isPrime(_ x: Int) -> Bool {
    if(x%2 == 0 || x%3 == 0){
        if(x == 2 || x == 3){
            return(true)
        }
        return(false)
    }
    else{
        //if the number is less than or equal to 1, we'll say it's not prime
        if(x <= 1){
            return(false)
        }


  }
    return true
}

This piece calculates the printing of the prime number from 1 to n.

func PrintPrimes(upTo n: Int) {
    for x in 1...n {
        var count = 0
        for num in 1..<x {
            isPrime(x)
            count += 1

        }
        if count <= 1 {
            print(isPrime(x))
        }
    }
}

This piece only runs twice and i'm not exactly sure why. I don't know if its because i'm not calling it correctly or I'd have to change up some calculations.

All help is appreciated

EDIT:

Here is the original printPrimes() before I decided to call isPrime within the function. This function calculates the prime numbers only and prints them up to n.

func printPrimes(upTo n: Int) {
    for x in 1...n {
        var count = 0
        for num in 1..<x {
            if x % num == 0 {
                count += 1
        }

    }
        if count <= 1 {
            print(x)
        }
   }
}
Kamanda
  • 305
  • 3
  • 4
  • 11
  • your code doesn't runs twice, it runs as expected, you see only 2 print statements because you have a conditional for when the count is less or equal than 1 (the first two iterations) – NicolasElPapu Oct 11 '19 at 16:51
  • Note that your method would return true for `49` and many other integers that are not prime – Leo Dabus Oct 11 '19 at 17:01
  • @NicolasElPapu Darn! so it's literally going forward then back? just two steps? If a play around with that I could get what i'm looking for then. – Kamanda Oct 11 '19 at 17:20
  • @Rob originally this was that code snippet was part for a printPrime numbers, the task asked me to rewrite it. I'm editing my question and adding the other function before all the cutting I did. Maybe it'll make more sense. – Kamanda Oct 11 '19 at 17:22
  • Also, the first routine looks like it was written in C. Setting aside the algorithmic issues, in Swift we generally would get rid of all of those parentheses. – Rob Oct 11 '19 at 17:26
  • OK, that “original” rendition for `printPrimes` makes complete sense. That is correct. So is the question just how do you “functionally decompose this” (i.e. how to pull the `isPrime` logic out of this routine)? – Rob Oct 11 '19 at 17:30

2 Answers2

1

Your second routine is printing only two values because it is calling isPrime, but never doing anything conditional on the value returned, but rather incrementing count regardless. And since you’re printing only if count is <= 1, that will happen only for the first two values of n.

But let’s say you were trying to print the prime numbers up to a certain number, you could do:

func printPrimes(upTo n: Int) {
    for x in 1...n {
        if isPrime(x) {
            print(x)
        }
    }
}

(As a matter of convention, in Swift, when we say “through n”, we’d iterate 1...n, and if someone said “up to n”, we’d iterate 1..<n. But because your original code snippet uses upTo in conjunction with 1...n, I’ll use that here, but just note that this isn’t very consistent with standard Swift API patterns.)

Unfortunately, isPrime is not correct, either. So you’ll have to fix that first. For example, consider 25. That is not divisible by 2 or 3, but isn’t prime, either.

If you look at the original printPrimes that was provided, what it effectively does is say “by how many whole integers less than x is x divisible ... if only divisible by one other number (namely 1), then it’s a prime.” That logic, although not efficient, is correct. You should go ahead and use that inside your isPrime routine. But that “is divisible by 2 or 3” logic is not correct.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Very detailed answer, helped alot, i'm going to switch up my isPrime function as my Tutor will definitely try break through it. – Kamanda Oct 11 '19 at 18:22
1

You can do it this way, in your printPrimes you can loop up to the number you want and just check if the number is prime by calling the function with the number. But you have to check your isPrime function. Your printPrimes should only do what its name says (print the prime numbers up to n) and all the logic to check if the number is prime should be on your isPrime function. Also its a good practice to use camelCase on functions, you should rename your function to printPrimes instead of PrintPrimes.

func printPrimes(upTo n: Int) {
    for x in 1...n {
        if isPrime(x) {
            print(x)
        }
    }
}
NicolasElPapu
  • 1,612
  • 2
  • 11
  • 26
  • 1
    Kudos for the camelCase, I need to start practicing good etiquette especially for the future! – Kamanda Oct 11 '19 at 18:30
  • 1
    Yes, no problem. They are little things, i forgot to mention it but as Rob said "through" usually includes the last number. Happy coding – NicolasElPapu Oct 11 '19 at 18:32