Last active
August 29, 2015 14:02
-
-
Save bnickel/7e070ab65dd5cdee621a to your computer and use it in GitHub Desktop.
Infinite prime sequences in Objective-C and Swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import Foundation; | |
@interface PrimeEnumerator : NSObject<NSFastEnumeration> | |
- (NSArray *)knownPrimes; | |
@end | |
@interface PrimeEnumerator () | |
@property (nonatomic, strong) NSMutableArray *primes; | |
@end | |
@implementation PrimeEnumerator | |
- (instancetype)init | |
{ | |
self = [super init]; | |
if (self) { | |
_primes = [NSMutableArray arrayWithObject:@2]; | |
} | |
return self; | |
} | |
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(__unsafe_unretained id [])buffer count:(NSUInteger)len | |
{ | |
if (state->state == 0) { | |
state->extra[0] = 0; | |
state->state = 1; | |
state->mutationsPtr = &(state->state); | |
} | |
unsigned long index = state->extra[0]; | |
unsigned long lastKnownPrime = state->extra[1]; | |
for (NSUInteger i = 0; i < len; i ++) { | |
if (index < self.primes.count) { | |
lastKnownPrime = [(buffer[i] = self.primes[index++]) unsignedLongValue]; | |
continue; | |
} | |
while ([self isDivisibleByKnownPrimes:++lastKnownPrime]) ; | |
NSNumber *primeNumber = @(lastKnownPrime); | |
buffer[i] = primeNumber; | |
[self.primes addObject:primeNumber]; | |
index = self.primes.count; | |
} | |
state->extra[0] = index; | |
state->extra[1] = lastKnownPrime; | |
state->itemsPtr = buffer; | |
return len; | |
} | |
- (BOOL)isDivisibleByKnownPrimes:(unsigned long)number | |
{ | |
unsigned long limit = ceilf(sqrtf(number)); | |
for (NSNumber *prime in self.primes) { | |
unsigned long primeValue = [prime unsignedIntegerValue]; | |
if (number % primeValue == 0) { | |
return YES; | |
} | |
if (primeValue > limit) { | |
break; | |
} | |
} | |
return NO; | |
} | |
- (NSArray *)knownPrimes | |
{ | |
return self.primes; | |
} | |
@end | |
int main(int argc, const char * argv[]) | |
{ | |
@autoreleasepool { | |
for (NSNumber *prime in [[PrimeEnumerator alloc] init]) { | |
if ([prime isGreaterThan:@1000]) { | |
break; | |
} | |
NSLog(@"%@", prime); | |
} | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
struct PrimeGenerator:GeneratorType { | |
let sequence:PrimeSequence | |
var index = 0 | |
init (_ sequence:PrimeSequence) { | |
self.sequence = sequence | |
} | |
mutating func next() -> Int? { | |
if index == sequence.knownPrimes.count { | |
sequence.findNextPrime() | |
} | |
return sequence.knownPrimes[index++] | |
} | |
} | |
class PrimeSequence:SequenceType { | |
var knownPrimes = [2] | |
func generate() -> PrimeGenerator { | |
return PrimeGenerator(self) | |
} | |
func findNextPrime() { | |
var lastKnownPrime = knownPrimes[knownPrimes.count - 1] | |
while isDivisibleByKnownPrimes(++lastKnownPrime) { } | |
knownPrimes.append(lastKnownPrime) | |
} | |
func isDivisibleByKnownPrimes(number:Int) -> Bool { | |
let limit = Int(ceilf(sqrtf(CFloat(number)))); | |
for prime in knownPrimes { | |
if number % prime == 0 { return true } | |
if prime > limit { break } | |
} | |
return false | |
} | |
} | |
for i in PrimeSequence() { | |
if i > 1000 { break } | |
println(i) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment