Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
54
Task/Fractran/Nim/fractran-1.nim
Normal file
54
Task/Fractran/Nim/fractran-1.nim
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import strutils
|
||||
import bignum
|
||||
|
||||
const PrimeProg = "17/91 78/85 19/51 23/38 29/33 77/29 95/23 77/19 1/17 11/13 13/11 15/14 15/2 55/1"
|
||||
|
||||
iterator values(prog: openArray[Rat]; init: Natural): Int =
|
||||
## Run the program "prog" with initial value "init" and yield the values.
|
||||
var n = newInt(init)
|
||||
var next: Rat
|
||||
while true:
|
||||
for fraction in prog:
|
||||
next = n * fraction
|
||||
if next.denom == 1:
|
||||
break
|
||||
n = next.num
|
||||
yield n
|
||||
|
||||
func toFractions(fractList: string): seq[Rat] =
|
||||
## Convert a string to a list of fractions.
|
||||
for f in fractList.split():
|
||||
result.add(newRat(f))
|
||||
|
||||
proc run(progStr: string; init, maxSteps: Natural = 0) =
|
||||
## Run the program described by string "progStr" with initial value "init",
|
||||
## stopping after "maxSteps" (0 means for ever).
|
||||
## Display the value after each step.
|
||||
let prog = progStr.toFractions()
|
||||
var stepCount = 0
|
||||
for val in prog.values(init):
|
||||
inc stepCount
|
||||
echo stepCount, ": ", val
|
||||
if stepCount == maxSteps:
|
||||
break
|
||||
|
||||
iterator primes(n: Natural): int =
|
||||
# Yield the list of first "n" primes.
|
||||
let prog = PrimeProg.toFractions()
|
||||
var count = 0
|
||||
for val in prog.values(2):
|
||||
if isZero(val and (val - 1)):
|
||||
# This is a power of two.
|
||||
yield val.digits(2) - 1 # Compute the exponent as number of binary digits minus one.
|
||||
inc count
|
||||
if count == n:
|
||||
break
|
||||
|
||||
# Run the program to compute primes displaying values at each step and stopping after 10 steps.
|
||||
echo "First ten steps for program to find primes:"
|
||||
PrimeProg.run(2, 10)
|
||||
|
||||
# Find the first 20 primes.
|
||||
echo "\nFirst twenty prime numbers:"
|
||||
for val in primes(20):
|
||||
echo val
|
||||
136
Task/Fractran/Nim/fractran-2.nim
Normal file
136
Task/Fractran/Nim/fractran-2.nim
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
import algorithm
|
||||
import sequtils
|
||||
import strutils
|
||||
import tables
|
||||
|
||||
const PrimeProg = "17/91 78/85 19/51 23/38 29/33 77/29 95/23 77/19 1/17 11/13 13/11 15/14 15/2 55/1"
|
||||
|
||||
type
|
||||
Fraction = tuple[num, denom: int]
|
||||
Factors = Table[int, int]
|
||||
FractranProg = object
|
||||
primes: seq[int]
|
||||
nums, denoms: seq[Factors]
|
||||
exponents: seq[int] # Could also use a CountTable.
|
||||
|
||||
iterator fractions(fractString: string): Fraction =
|
||||
## Extract fractions from a string and yield them.
|
||||
for f in fractString.split():
|
||||
let fields = f.strip().split('/')
|
||||
assert fields.len == 2
|
||||
yield (fields[0].parseInt(), fields[1].parseInt())
|
||||
|
||||
iterator factors(val: int): tuple[val, exp: int] =
|
||||
## Extract factors from a positive integer.
|
||||
|
||||
# Extract factor 2.
|
||||
var val = val
|
||||
var exp = 0
|
||||
while (val and 1) == 0:
|
||||
inc exp
|
||||
val = val shr 1
|
||||
if exp != 0:
|
||||
yield (2, exp)
|
||||
|
||||
# Extract odd factors.
|
||||
var d = 3
|
||||
while d <= val:
|
||||
exp = 0
|
||||
while val mod d == 0:
|
||||
inc exp
|
||||
val = val div d
|
||||
if exp != 0:
|
||||
yield (d, exp)
|
||||
inc d, 2
|
||||
|
||||
func newProg(fractString: string; init: int): FractranProg =
|
||||
## Initialize a Fractran program.
|
||||
|
||||
for f in fractString.fractions():
|
||||
# Extract numerators factors.
|
||||
var facts: Factors
|
||||
for (val, exp) in f.num.factors():
|
||||
result.primes.add(val)
|
||||
facts[val] = exp
|
||||
result.nums.add(facts)
|
||||
# Extract denominator factors.
|
||||
facts.clear()
|
||||
for (val, exp) in f.denom.factors():
|
||||
result.primes.add(val)
|
||||
facts[val] = exp
|
||||
result.denoms.add(facts)
|
||||
|
||||
# Finalize list of primes.
|
||||
result.primes.sort()
|
||||
result.primes = result.primes.deduplicate(true)
|
||||
|
||||
# Allocate and initialize exponent sequence.
|
||||
result.exponents.setLen(result.primes[^1] + 1)
|
||||
for (val, exp) in init.factors():
|
||||
result.exponents[val] = exp
|
||||
|
||||
func doOneStep(prog: var FractranProg): bool =
|
||||
## Execute one step of the program.
|
||||
|
||||
for idx, factor in prog.denoms:
|
||||
block tryFraction:
|
||||
for val, exp in factor.pairs():
|
||||
if prog.exponents[val] < exp:
|
||||
# Not a multiple of the denominator.
|
||||
break tryFraction
|
||||
# Divide by the denominator.
|
||||
for val, exp in factor.pairs():
|
||||
dec prog.exponents[val], exp
|
||||
# Multiply by the numerator.
|
||||
for val, exp in prog.nums[idx]:
|
||||
inc prog.exponents[val], exp
|
||||
return true
|
||||
|
||||
func `$`(prog: FractranProg): string =
|
||||
## Display a value as a product of prime factors.
|
||||
|
||||
for val, exp in prog.exponents:
|
||||
if exp != 0:
|
||||
if result.len > 0:
|
||||
result.add('.')
|
||||
result.add($val)
|
||||
if exp > 1:
|
||||
result.add('^')
|
||||
result.add($exp)
|
||||
|
||||
proc run(fractString: string; init: int; maxSteps = 0) =
|
||||
## Run a Fractran program.
|
||||
|
||||
var prog = newProg(fractString, init)
|
||||
|
||||
var stepCount = 0
|
||||
while stepCount < maxSteps:
|
||||
if not prog.doOneStep():
|
||||
echo "*** No more possible fraction. Program stopped."
|
||||
return
|
||||
inc stepCount
|
||||
echo stepCount, ": ", prog
|
||||
|
||||
proc findPrimes(maxCount: int) =
|
||||
## Search and print primes.
|
||||
|
||||
var prog = newProg(PrimeProg, 2)
|
||||
let oddPrimes = prog.primes[1..^1]
|
||||
var primeCount = 0
|
||||
while primeCount < maxCount:
|
||||
discard prog.doOneStep()
|
||||
block powerOf2:
|
||||
if prog.exponents[2] > 0:
|
||||
for p in oddPrimes:
|
||||
if prog.exponents[p] != 0:
|
||||
# Not a power of 2.
|
||||
break powerOf2
|
||||
inc primeCount
|
||||
echo primeCount, ": ", prog.exponents[2]
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
echo "First ten steps for program to find primes:"
|
||||
run(PrimeProg, 2, 10)
|
||||
echo "\nFirst twenty prime numbers:"
|
||||
findPrimes(20)
|
||||
Loading…
Add table
Add a link
Reference in a new issue