From d7bd1decc9c985988992ecbba4c0c07918d48f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oscar=20Bystr=C3=B6m=20Ericsson?= Date: Fri, 24 Nov 2023 10:45:32 +0100 Subject: [PATCH] Get first one thousand or one million primes option (#114). --- Sources/NBKCoreKit/Models/NBKPrimeSieve.swift | 11 +++++++ .../Models/NBKPrimeSieve.swift | 20 +++++++++---- .../Models/NBKPrimeSieve.swift | 30 ++++++++++++++++--- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/Sources/NBKCoreKit/Models/NBKPrimeSieve.swift b/Sources/NBKCoreKit/Models/NBKPrimeSieve.swift index 4fd02746..4255abaa 100644 --- a/Sources/NBKCoreKit/Models/NBKPrimeSieve.swift +++ b/Sources/NBKCoreKit/Models/NBKPrimeSieve.swift @@ -30,12 +30,23 @@ // MARK: Initializers //=------------------------------------------------------------------------= + /// Generates a list of the first `count` number of primes. + public init(first count: PrimeCountLimit) { + self.init(through: count.rawValue) + } + /// Generates a list of all primes from zero through `limit`. public init(through limit: UInt) { self._limit = limit self._elements = [] Self.primesByEratosthenes(through: limit, appending: &self._elements) } + + //*========================================================================* + // MARK: * Prime Count Limit + //*========================================================================* + + public enum PrimeCountLimit: UInt { case thousand = 7919, million = 15485863 } } //=----------------------------------------------------------------------------= diff --git a/Tests/NBKCoreKitBenchmarks/Models/NBKPrimeSieve.swift b/Tests/NBKCoreKitBenchmarks/Models/NBKPrimeSieve.swift index 08fce6de..cf59ff34 100644 --- a/Tests/NBKCoreKitBenchmarks/Models/NBKPrimeSieve.swift +++ b/Tests/NBKCoreKitBenchmarks/Models/NBKPrimeSieve.swift @@ -25,37 +25,37 @@ final class NBKPrimeSieveBenchmarks: XCTestCase { //=------------------------------------------------------------------------= func test1000X1() { - for _ in 0 ... 1000 { + for _ in 0 ..< 1000 { NBK.blackHole(T(through: 1)) } } func test1000X10() { - for _ in 0 ... 1000 { + for _ in 0 ..< 1000 { NBK.blackHole(T(through: 10)) } } func test1000X100() { - for _ in 0 ... 1000 { + for _ in 0 ..< 1000 { NBK.blackHole(T(through: 100)) } } func test1000X1000() { - for _ in 0 ... 1000 { + for _ in 0 ..< 1000 { NBK.blackHole(T(through: 1000)) } } func test1000X10000() { - for _ in 0 ... 1000 { + for _ in 0 ..< 1000 { NBK.blackHole(T(through: 10000)) } } func test1000X100000() { - for _ in 0 ... 1000 { + for _ in 0 ..< 1000 { NBK.blackHole(T(through: 100000)) } } @@ -64,6 +64,14 @@ final class NBKPrimeSieveBenchmarks: XCTestCase { // MARK: Tests x No Loop //=------------------------------------------------------------------------= + func testNoLoopFirst1000() { + NBK.blackHole(T(first: .thousand)) + } + + func testNoLoopFirst1000000() { + NBK.blackHole(T(first: .million)) + } + func testNoLoop1E6() { NBK.blackHole(T(through: 1000000)) } diff --git a/Tests/NBKCoreKitTests/Models/NBKPrimeSieve.swift b/Tests/NBKCoreKitTests/Models/NBKPrimeSieve.swift index 9b480ba3..1963a138 100644 --- a/Tests/NBKCoreKitTests/Models/NBKPrimeSieve.swift +++ b/Tests/NBKCoreKitTests/Models/NBKPrimeSieve.swift @@ -22,7 +22,6 @@ final class NBKPrimeSieveTests: XCTestCase { // MARK: State //=------------------------------------------------------------------------= - // - TODO: Replace these with a 1-million-primes text file. static let primes: [UInt] = [ 0002, 0003, 0005, 0007, 0011, 0013, 0017, 0019, 0023, 0029, 0031, 0037, 0041, 0043, 0047, 0053, 0059, 0061, 0067, 0071, @@ -171,13 +170,36 @@ final class NBKPrimeSieveTests: XCTestCase { check(through: 10000, expectation: Self.primes.prefix(1229)) } + func testPrimesThroughPrimeCountLimit() { + brr: do { + let result = T(first: .thousand) + XCTAssertEqual(result.elements.count, 1000) + XCTAssertEqual(result.elements.last!, 7919) + XCTAssertEqual(result.elements.last!, result.limit) + check(result, limit: Self.primes[999], elements: Self.primes[...999]) + } + + #if !DEBUG // fast in RELEASE, slow in DEBUG + brr: do { + let result = T(first: .million) + XCTAssertEqual(result.elements.count, 01000000) + XCTAssertEqual(result.elements.last!, 15485863) + XCTAssertEqual(result.elements.last!, result.limit) + } + #endif + } + //=------------------------------------------------------------------------= // MARK: Assertions //=------------------------------------------------------------------------= func check(through limit: UInt, expectation: ArraySlice, file: StaticString = #file, line: UInt = #line) { - let result = T(through: limit) - XCTAssertEqual(result.limit, limit, file: file, line: line) - XCTAssertEqual(result.elements[...], expectation, file: file, line: line) + check(T(through: limit), limit: limit, elements: expectation, file: file, line: line) + } + + func check(_ sieve: T, limit: UInt, elements: ArraySlice, file: StaticString = #file, line: UInt = #line) { + XCTAssertEqual(sieve.limit, limit, file: file, line: line) + XCTAssertEqual(sieve.elements[...], (elements), file: file, line: line) + XCTAssertLessThanOrEqual(sieve.elements.last ?? 0000, limit, file: file, line: line) } }