I'm trying to find the nth prime number in xCode's Swift, but I can't seem to get this working, it just gives a list of prime numbers.
func nthPrimeNumber (n: Int) -> Int
{
var prime: Int
var divisor: Int
var isPrime: Bool
for (prime = 2; prime <= 50; ++prime )
{
isPrime = true;
for (divisor = 2; divisor < prime; ++divisor )
{
if ((prime % divisor) == 0 )
{
isPrime = false
}
}
if (isPrime == true )
{
println(" \(prime)")
}
}
return prime
}
Making minimal changes to your code, but, as commenter said, adding termination logic:
func nthPrimeNumber(n: Int) -> Int {
var prime: Int
var divisor: Int
var isPrime: Bool
var counter = 0
for (prime = 2; prime <= 50 && counter < n; ++prime )
{
isPrime = true;
for (divisor = 2; divisor < prime; ++divisor )
{
if ((prime % divisor) == 0 )
{
isPrime = false
}
}
if (isPrime)
{
counter++
}
}
return prime-1
}
extension FixedWidthInteger {
var isPrime: Bool {
if self < 2 { return false }
let squareRoot = Self(Double(self).squareRoot())
if squareRoot * squareRoot == self { return false }
for i in 2..<Self(Double(self).squareRoot().rounded(.up)) where self % i == 0 {
return false
}
return true
}
}
let twoDigitsPrimeNumbers = (1..<100).filter { $0.isPrime }
print(twoDigitsPrimeNumbers) // [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
func nthPrime(nth: Int)-> Int {
var primeCounter = 0
var number = 2
while true {
if number.isPrime {
primeCounter += 1
if nth == primeCounter { return number }
}
number += 1
}
}
nthPrime(1000) // 7,919
[Note: this code returns the nth
prime, as required; not just 50 or 51, both non-primes.]
The n
that you specified as an argument is totally ignored thus your computation terminated if and when prime
became 51
. All the primes under 50
were printed and a coincidental 51
is returned. If you want the nth prime, you need to a) count up the primes as you encounter them and b) stop when you've got the nth.
You also have the issue to deal with of 'I want the 20th prime but I'm only looking for primes under 50' - there might not be a prime.
And, you are performing prime % divisor
with divisor < prime
but that divisor never needs to be more than prime/2
.
All this together, with improvement in style leads to:
func nthPrimeNumber (var n: Int) -> Int
{
if n < 1 { return 0 } // error condition
var prime = 2
while (true) { // find the `nth` no matter how large `prime`
var isPrime = true
for (var divisor = 2; divisor <= prime/2; ++divisor) {
if 0 == prime % divisor { isPrime = false; break }
}
if isPrime {
println (" \(prime)")
if 0 == --n { return prime }
}
prime++
}
}
and some results:
39> nthPrimeNumber(1)
2
$R7: (Int) = 2
40> nthPrimeNumber(3)
2
3
5
$R8: (Int) = 5
41> nthPrimeNumber(10)
2
3
5
7
11
13
17
19
23
29
$R9: (Int) = 29
I encourage you to try n
of 1000
!