Ormiston triples: Difference between revisions
Content added Content deleted
No edit summary |
(Created Nim solution.) |
||
Line 914: | Line 914: | ||
Ormiston triples before 1 billion: 368 |
Ormiston triples before 1 billion: 368 |
||
Ormiston triples before 10 billion: 4925 |
Ormiston triples before 10 billion: 4925 |
||
</pre> |
|||
=={{header|Nim}}== |
|||
<syntaxhighlight lang="Nim">import std/[algorithm, bitops, math, strformat, strutils] |
|||
type Sieve = object |
|||
data: seq[byte] |
|||
func `[]`(sieve: Sieve; idx: Positive): bool = |
|||
## Return value of element at index "idx". |
|||
let idx = idx shr 1 |
|||
let iByte = idx shr 3 |
|||
let iBit = idx and 7 |
|||
result = sieve.data[iByte].testBit(iBit) |
|||
func `[]=`(sieve: var Sieve; idx: Positive; val: bool) = |
|||
## Set value of element at index "idx". |
|||
let idx = idx shr 1 |
|||
let iByte = idx shr 3 |
|||
let iBit = idx and 7 |
|||
if val: sieve.data[iByte].setBit(iBit) |
|||
else: sieve.data[iByte].clearBit(iBit) |
|||
func initSieve(lim: Positive): Sieve = |
|||
## Initialize a sieve from 2 to "lim". |
|||
result.data = newSeq[byte]((lim + 16) shr 4) |
|||
result[1] = true |
|||
for n in countup(3, sqrt(lim.toFloat).int, 2): |
|||
if not result[n]: |
|||
for k in countup(n * n, lim, 2 * n): |
|||
result[k] = true |
|||
func isPrime(sieve: Sieve; n: int): bool = |
|||
## Return true if "n" is prime. |
|||
result = if (n and 1) == 0: n == 2 else: not sieve[n] |
|||
func nextPrime(sieve: Sieve; n: int): int = |
|||
## Return next prime greater than "n". |
|||
result = n |
|||
while true: |
|||
inc result |
|||
if sieve.isPrime(result): |
|||
return |
|||
func digits(n: Positive): seq[byte] = |
|||
## Return the sorted list of digits of "n". |
|||
var n = n.Natural |
|||
while n != 0: |
|||
result.add byte(n mod 10) |
|||
n = n div 10 |
|||
result.sort() |
|||
proc main() = |
|||
const N = 10_000_000_000 |
|||
let sieve = initSieve(N) |
|||
echo "Smallest member of the first 25 Ormiston triples:" |
|||
var count = 0 |
|||
var limit = N div 10 |
|||
var p1 = 2 |
|||
while true: |
|||
if p1 >= limit: |
|||
echo &"Number of Ormiston pairs below {insertSep($limit)}: {count}" |
|||
limit *= 10 |
|||
if limit > N: break |
|||
# Check p1 and p2. |
|||
let p2 = sieve.nextPrime(p1) |
|||
if (p2 - p1) mod 18 != 0: |
|||
p1 = p2 |
|||
continue |
|||
# Check p2 and p3. |
|||
let p3 = sieve.nextPrime(p2) |
|||
if (p3 - p2) mod 18 != 0: |
|||
p1 = p3 # Skip p2. |
|||
continue |
|||
# Check p1.digits and p2.digits. |
|||
let d1 = p1.digits |
|||
if p2.digits != d1: |
|||
p1 = p2 |
|||
continue |
|||
# Check p1.digits and p3.digits. |
|||
if p3.digits != d1: |
|||
p1 = p3 # Skip p2. |
|||
continue |
|||
# Ormiston triple found. |
|||
inc count |
|||
if count <= 25: |
|||
stdout.write &"{p1:8}" |
|||
stdout.write if count mod 5 == 0: '\n' else: ' ' |
|||
if count == 25: echo() |
|||
# Try next. |
|||
p1 = p2 |
|||
main() |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Smallest member of the first 25 Ormiston triples: |
|||
11117123 12980783 14964017 32638213 32964341 |
|||
33539783 35868013 44058013 46103237 48015013 |
|||
50324237 52402783 58005239 60601237 61395239 |
|||
74699789 76012879 78163123 80905879 81966341 |
|||
82324237 82523017 83279783 86050781 92514341 |
|||
Number of Ormiston pairs below 1_000_000_000: 368 |
|||
Number of Ormiston pairs below 10_000_000_000: 4925 |
|||
</pre> |
</pre> |
||