-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path11. Sieve of Eratosthenes. CountSemiprimes.swift
77 lines (62 loc) · 2.8 KB
/
11. Sieve of Eratosthenes. CountSemiprimes.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import Foundation
import Glibc
// Solution @ Sergey Leschev, Belarusian State University
// 11. Sieve of Eratosthenes. CountSemiprimes.
// A prime is a positive integer X that has exactly two distinct divisors: 1 and X. The first few prime integers are 2, 3, 5, 7, 11 and 13.
// A semiprime is a natural number that is the product of two (not necessarily distinct) prime numbers. The first few semiprimes are 4, 6, 9, 10, 14, 15, 21, 22, 25, 26.
// You are given two non-empty arrays P and Q, each consisting of M integers. These arrays represent queries about the number of semiprimes within specified ranges.
// Query K requires you to find the number of semiprimes within the range (P[K], Q[K]), where 1 ≤ P[K] ≤ Q[K] ≤ N.
// For example, consider an integer N = 26 and arrays P, Q such that:
// P[0] = 1 Q[0] = 26
// P[1] = 4 Q[1] = 10
// P[2] = 16 Q[2] = 20
// The number of semiprimes within each of these ranges is as follows:
// (1, 26) is 10,
// (4, 10) is 4,
// (16, 20) is 0.
// Write a function:
// class Solution { public int[] solution(int N, int[] P, int[] Q); }
// that, given an integer N and two non-empty arrays P and Q consisting of M integers, returns an array consisting of M elements specifying the consecutive answers to all the queries.
// For example, given an integer N = 26 and arrays P, Q such that:
// P[0] = 1 Q[0] = 26
// P[1] = 4 Q[1] = 10
// P[2] = 16 Q[2] = 20
// the function should return the values [10, 4, 0], as explained above.
// Write an efficient algorithm for the following assumptions:
// N is an integer within the range [1..50,000];
// M is an integer within the range [1..30,000];
// each element of arrays P and Q is an integer within the range [1..N];
// P[i] ≤ Q[i].
public func solution(_ N: Int, _ P : inout [Int], _ Q : inout [Int]) -> [Int] {
guard N > 1 else { return [0] }
var primeNumbers = Set<Int>()
var compositeNumbers = [Int: Int]()
var semiprimes = Set<Int>()
var semiprimesPrefixSums = [Int: Int]()
semiprimesPrefixSums[0] = 0
var sum = 0
var result = [Int]()
for number in 2...N {
guard compositeNumbers[number] == nil else { continue }
primeNumbers.insert(number)
var k = number * number
while k <= N {
compositeNumbers[k] = number
k += number
}
}
for entry in compositeNumbers {
let factor = entry.key / entry.value
if primeNumbers.contains(factor) { semiprimes.insert(entry.key) }
}
for i in 1...N {
if semiprimes.contains(i) { sum += 1 }
semiprimesPrefixSums[i] = sum
}
for i in 0..<P.count {
let left = semiprimesPrefixSums[P[i] - 1]!
let right = semiprimesPrefixSums[Q[i]]!
result.append(right - left)
}
return result
}