Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
89
Task/Sisyphus-sequence/Nim/sisyphus-sequence.nim
Normal file
89
Task/Sisyphus-sequence/Nim/sisyphus-sequence.nim
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import std/[bitops, math, strformat, strutils, tables]
|
||||
|
||||
# Sieve which uses only one bit for odd integers.
|
||||
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]
|
||||
|
||||
let sieve = initSieve(700_000_000)
|
||||
|
||||
func nextPrime(sieve: Sieve; n: int): int =
|
||||
## Return next prime greater than "n".
|
||||
result = n
|
||||
while true:
|
||||
inc result
|
||||
if sieve.isPrime(result):
|
||||
return
|
||||
|
||||
var p = 0 # Current prime (none for now).
|
||||
var count = 0 # Count of elements in sequence.
|
||||
var n = 1 # Last element of sequence.
|
||||
var counts: CountTable[int] # Count of occurrences for value < 250.
|
||||
echo "First 100 terms of the Sisyphus sequence:"
|
||||
|
||||
while count < 100_000_000:
|
||||
|
||||
# Process current number.
|
||||
inc count
|
||||
if count <= 100:
|
||||
stdout.write &"{n:3}"
|
||||
stdout.write if count mod 10 == 0: '\n' else: ' '
|
||||
if count == 100: echo()
|
||||
elif count in [1_000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000]:
|
||||
echo &"The {insertSep($count)}th term is {insertSep($n)} " &
|
||||
&"and the highest prime needed is {insertSep($p)}."
|
||||
|
||||
# Update count table.
|
||||
if n < 250: counts.inc(n)
|
||||
|
||||
# Find next term of the sequence.
|
||||
if (n and 1) == 0:
|
||||
n = n shr 1
|
||||
else:
|
||||
p = sieve.nextPrime(p)
|
||||
inc n, p
|
||||
|
||||
echo()
|
||||
echo "Numbers under 250 which don’t occur in the first 100_000_000 terms:"
|
||||
for n in 1..249:
|
||||
if n notin counts:
|
||||
stdout.write " ", n
|
||||
echo '\n'
|
||||
|
||||
echo "Numbers under 250 which occur the most in the first 100_000_000 terms:"
|
||||
counts.sort()
|
||||
let largest = counts.largest[1]
|
||||
for (n, count) in counts.pairs:
|
||||
if count == largest:
|
||||
stdout.write " ", n
|
||||
else:
|
||||
# No more value with the largest number of occurrences.
|
||||
echo()
|
||||
break
|
||||
Loading…
Add table
Add a link
Reference in a new issue