Unprimeable numbers: Difference between revisions
Content added Content deleted
(Added Swift solution) |
|||
Line 2,470: | Line 2,470: | ||
First unprimeable that ends with 8: 208 |
First unprimeable that ends with 8: 208 |
||
First unprimeable that ends with 9: 212159 |
First unprimeable that ends with 9: 212159 |
||
</pre> |
|||
=={{header|Swift}}== |
|||
{{trans|Rust}} |
|||
<lang swift>class BitArray { |
|||
var array: [UInt32] |
|||
init(size: Int) { |
|||
self.array = Array(repeating: 0, count: (size + 31)/32) |
|||
} |
|||
func get(index: Int) -> Bool { |
|||
let bit = UInt32(1) << (index & 31) |
|||
return (self.array[index >> 5] & bit) != 0 |
|||
} |
|||
func set(index: Int, value: Bool) { |
|||
let bit = UInt32(1) << (index & 31) |
|||
if value { |
|||
self.array[index >> 5] |= bit |
|||
} else { |
|||
self.array[index >> 5] &= ~bit |
|||
} |
|||
} |
|||
} |
|||
class PrimeSieve { |
|||
var composite: BitArray |
|||
init(size: Int) { |
|||
self.composite = BitArray(size: size/2) |
|||
var p = 3 |
|||
while p * p <= size { |
|||
if !self.composite.get(index: p/2 - 1) { |
|||
let inc = p * 2 |
|||
var q = p * p |
|||
while q <= size { |
|||
self.composite.set(index: q/2 - 1, value: true) |
|||
q += inc |
|||
} |
|||
} |
|||
p += 2 |
|||
} |
|||
} |
|||
func isPrime(number: Int) -> Bool { |
|||
if number < 2 { |
|||
return false |
|||
} |
|||
if (number & 1) == 0 { |
|||
return number == 2 |
|||
} |
|||
return !self.composite.get(index: number/2 - 1) |
|||
} |
|||
} |
|||
// return number of decimal digits |
|||
func countDigits(number: Int) -> Int { |
|||
var digits = 0 |
|||
var n = number |
|||
while n > 0 { |
|||
n /= 10 |
|||
digits += 1 |
|||
} |
|||
return digits |
|||
} |
|||
// return the number with one digit replaced |
|||
func changeDigit(number: Int, index: Int, digit: Int) -> Int { |
|||
var p = 1 |
|||
var changed = 0 |
|||
var n = number |
|||
var i = index |
|||
while i > 0 { |
|||
changed += p * (n % 10) |
|||
p *= 10 |
|||
n /= 10 |
|||
i -= 1 |
|||
} |
|||
changed += (10 * (n / 10) + digit) * p |
|||
return changed |
|||
} |
|||
func unprimeable(sieve: PrimeSieve, number: Int) -> Bool { |
|||
if sieve.isPrime(number: number) { |
|||
return false |
|||
} |
|||
for i in 0..<countDigits(number: number) { |
|||
for j in 0..<10 { |
|||
let n = changeDigit(number: number, index: i, digit: j) |
|||
if n != number && sieve.isPrime(number: n) { |
|||
return false |
|||
} |
|||
} |
|||
} |
|||
return true |
|||
} |
|||
var count = 0 |
|||
var n = 100 |
|||
var lowest = Array(repeating: 0, count: 10) |
|||
var found = 0 |
|||
let sieve = PrimeSieve(size: 10000000) |
|||
print("First 35 unprimeable numbers:") |
|||
while count < 600 || found < 10 { |
|||
if unprimeable(sieve: sieve, number: n) { |
|||
if count < 35 { |
|||
if count > 0 { |
|||
print(", ", terminator: "") |
|||
} |
|||
print(n, terminator: "") |
|||
} |
|||
count += 1 |
|||
if count == 600 { |
|||
print("\n600th unprimeable number: \(n)") |
|||
} |
|||
let lastDigit = n % 10 |
|||
if lowest[lastDigit] == 0 { |
|||
lowest[lastDigit] = n |
|||
found += 1 |
|||
} |
|||
} |
|||
n += 1 |
|||
} |
|||
for i in 0..<10 { |
|||
print("Least unprimeable number ending in \(i): \(lowest[i])") |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
First 35 unprimeable numbers: |
|||
200, 204, 206, 208, 320, 322, 324, 325, 326, 328, 510, 512, 514, 515, 516, 518, 530, 532, 534, 535, 536, 538, 620, 622, 624, 625, 626, 628, 840, 842, 844, 845, 846, 848, 890 |
|||
600th unprimeable number: 5242 |
|||
Least unprimeable number ending in 0: 200 |
|||
Least unprimeable number ending in 1: 595631 |
|||
Least unprimeable number ending in 2: 322 |
|||
Least unprimeable number ending in 3: 1203623 |
|||
Least unprimeable number ending in 4: 204 |
|||
Least unprimeable number ending in 5: 325 |
|||
Least unprimeable number ending in 6: 206 |
|||
Least unprimeable number ending in 7: 872897 |
|||
Least unprimeable number ending in 8: 208 |
|||
Least unprimeable number ending in 9: 212159 |
|||
</pre> |
</pre> |
||