Primes and Factors

A few points: * Your firstNPrimes function is changing state outside the function. This is almost always a bad thing. You should bring the arrayOfPrimes inside the function and return it at the end. * Your nested "for" loop is really just searching for the first factor in the list of primes. You can do this with a lazy filter if you want. * You're checking on each iteration of the "for" loop to see if you've gone over the limit. You can remember the limit from the previous loop and increment this limit by only comparing with larger numbers (something which would typically only involve one comparison per loop rather than all old numbers).

This would then look like this:

// Func now returns the array of primes
func firstNPrimes(n:Int) -> [Int] {
    var arrayOfPrimes = [2]
    var numberToTest = 3
    var limit = 0 // Initial limit is index zero ("2" is larger than the square root of 3)

    while arrayOfPrimes.count < n {
        // Search for the first factor of "numberToTest" in the arrayOfPrimes below index "limit"
        if arrayOfPrimes[0..<limit].lazy.filter({ numberToTest % $0 == 0 }).first == nil {
            arrayOfPrimes.append(numberToTest)
        }

        numberToTest += 2

        // The next limit will be the first number greater than the square root of "numberToTest"
        let root = Int(sqrt(Double(numberToTest)))

        // Look for the next limit, starting at the old limit
        limit = arrayOfPrimes[limit..<arrayOfPrimes.count].enumerate().lazy.filter { (index, prime) in
            prime > root
        }.first?.index.advancedBy(limit) ?? arrayOfPrimes.count
    }
    return arrayOfPrimes
}

firstNPrimes(25) // returns an array of all primes less than 100
/r/swift Thread