Update all new Tasks

This commit is contained in:
Ingy döt Net 2015-02-20 09:02:09 -05:00
parent 00a190b0a6
commit 91df62d461
5697 changed files with 93386 additions and 804 deletions

View file

@ -0,0 +1,37 @@
'''[[wp:FRACTRAN|FRACTRAN]]''' is a Turing-complete esoteric programming language invented by the mathematician [[wp:John Horton Conway|John Horton Conway]].
A FRACTRAN program is an ordered list of positive fractions <math>P = (f_1, f_2, \ldots, f_m)</math>, together with an initial positive integer input <math>n</math>.
The program is run by updating the integer <math>n</math> as follows:
* for the first fraction, <math>f_i</math>, in the list for which <math>nf_i</math> is an integer, replace <math>n</math> with <math>nf_i</math> ;
* repeat this rule until no fraction in the list produces an integer when multiplied by <math>n</math>, then halt.
Conway gave a program for primes in FRACTRAN:
: <math>17/91</math>, <math>78/85</math>, <math>19/51</math>, <math>23/38</math>, <math>29/33</math>, <math>77/29</math>, <math>95/23</math>, <math>77/19</math>, <math>1/17</math>, <math>11/13</math>, <math>13/11</math>, <math>15/14</math>, <math>15/2</math>, <math>55/1</math>
Starting with <math>n=2</math>, this FRACTRAN program will change <math>n</math> to <math>15=2\times (15/2)</math>, then <math>825=15\times (55/1)</math>, generating the following sequence of integers:
: <math>2</math>, <math>15</math>, <math>825</math>, <math>725</math>, <math>1925</math>, <math>2275</math>, <math>425</math>, <math>390</math>, <math>330</math>, <math>290</math>, <math>770</math>, <math>\ldots</math>
After 2, this sequence contains the following powers of 2:
:<math>2^2=4</math>, <math>2^3=8</math>, <math>2^5=32</math>, <math>2^7=128</math>, <math>2^{11}=2048</math>, <math>2^{13}=8192</math>, <math>2^{17}=131072</math>, <math>2^{19}=524288</math>, <math>\ldots</math>
which are the prime powers of 2.
'''Your task''' is to
write a program that reads a list of fractions in a ''natural'' format from the keyboard or from a string,
to parse it into a sequence of fractions (''i.e.'' two integers),
and runs the FRACTRAN starting from a provided integer, writing the result at each step.
It is also required that the number of step is limited (by a parameter easy to find).
'''Extra credit:''' Use this program to derive the first 20 or so prime numbers.
For more on how to program FRACTRAN as a universal programming language, see:
* J. H. Conway (1987). Fractran: A Simple Universal Programming Language for Arithmetic. In: Open Problems in Communication and Computation, pages 426. Springer.
* J. H. Conway (2010). "FRACTRAN: A simple universal programming language for arithmetic". In Jeffrey C. Lagarias. The Ultimate Challenge: the 3x+1 problem. American Mathematical Society. pp. 249264. ISBN 978-0-8218-4940-8. Zbl 1216.68068.
* [http://scienceblogs.com/goodmath/2006/10/27/prime-number-pathology-fractra/Prime Number Pathology: Fractran] by Mark C. Chu-Carroll; October 27, 2006.

View file

@ -0,0 +1,43 @@
with Ada.Text_IO;
procedure Fractan is
type Fraction is record Nom: Natural; Denom: Positive; end record;
type Frac_Arr is array(Positive range <>) of Fraction;
function "/" (N: Natural; D: Positive) return Fraction is
Frac: Fraction := (Nom => N, Denom => D);
begin
return Frac;
end "/";
procedure F(List: Frac_Arr; Start: Positive; Max_Steps: Natural) is
N: Positive := Start;
J: Positive;
begin
Ada.Text_IO.Put(" 0:" & Integer'Image(N) & " ");
for I in 1 .. Max_Steps loop
J := List'First;
loop
if N mod List(J).Denom = 0 then
N := (N/List(J).Denom) * List(J).Nom;
exit; -- found fraction
elsif J >= List'Last then
return; -- did try out all fractions
else
J := J + 1; -- try the next fraction
end if;
end loop;
Ada.Text_IO.Put(Integer'Image(I) & ":" & Integer'Image(N) & " ");
end loop;
end F;
begin
-- F((2/3, 7/2, 1/5, 1/7, 1/9, 1/4, 1/8), 2, 100);
-- output would be "0: 2 1: 7 2: 1" and then terminate
F((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),
2, 15);
-- output is "0: 2 1: 15 2: 825 3: 725 ... 14: 132 15: 116"
end Fractan;

View file

@ -0,0 +1,24 @@
n := 2, steplimit := 15, numerator := [], denominator := []
s := "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"
Loop, Parse, s, % A_Space
if (!RegExMatch(A_LoopField, "^(\d+)/(\d+)$", m))
MsgBox, % "Invalid input string (" A_LoopField ")."
else
numerator[A_Index] := m1, denominator[A_Index] := m2
SetFormat, FloatFast, 0.0
Gui, Add, ListView, R10 W100 -Hdr, |
SysGet, VSBW, 2
LV_ModifyCol(1, 95 - VSBW), LV_Add( , 0 ": " n)
Gui, Show
Loop, % steplimit {
i := A_Index
Loop, % numerator.MaxIndex()
if (!Mod(nn := n * numerator[A_Index] / denominator[A_Index], 1)) {
LV_Modify(LV_Add( , i ": " (n := nn)), "Vis")
continue, 2
}
break
}

View file

@ -0,0 +1,36 @@
(fractran=
np n fs A Z fi P p N L M
. !arg:(?N,?n,?fs) {Number of iterations, start n, fractions}
& :?P:?L {Initialise accumulators.}
& whl
' ( -1+!N:>0:?N {Stop when counted down to zero.}
& !n !L:?L {Prepend all numbers to result list.}
& (2\L!n:#?p&!P !p:?P|) {If log2(n) is rational, append it to list of primes.}
& !fs:? (/?fi&!n*!fi:~/:?n) ? {This line does the following (See task description):
"for the first fraction, fi, in the list for which
nfi is an integer, replace n by nfi ;"}
)
& :?M
& whl'(!L:%?n ?L&!n !M:?M) {Invert list of numbers. (append to long list is
very expensive. Better to prepend and finally invert.}
& (!M,!P) {Return the two lists}
);
( clk$:?t0
& fractran$(430000, 2, 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)
: (?numbers,?primes)
& lst$(numbers,"numbers.lst",NEW)
& put$("
FRACTRAN found these primes:"
!primes
"\nThe list of numbers is saved in numbers.txt
The biggest number in the list is"
( 0:?max
& !numbers:? (>%@!max:?max&~) ?
| !max
)
str$("\ntime: " flt$(clk$+-1*!t0,4) " sec\n")
, "FRACTRAN.OUT",NEW)
);

View file

@ -0,0 +1,64 @@
#include <iostream>
#include <sstream>
#include <iterator>
#include <vector>
#include <math.h>
using namespace std;
class fractran
{
public:
void run( std::string p, int s, int l )
{
start = s; limit = l;
istringstream iss( p ); vector<string> tmp;
copy( istream_iterator<string>( iss ), istream_iterator<string>(), back_inserter<vector<string> >( tmp ) );
string item; vector< pair<float, float> > v;
pair<float, float> a;
for( vector<string>::iterator i = tmp.begin(); i != tmp.end(); i++ )
{
string::size_type pos = ( *i ).find( '/', 0 );
if( pos != std::string::npos )
{
a = make_pair( atof( ( ( *i ).substr( 0, pos ) ).c_str() ), atof( ( ( *i ).substr( pos + 1 ) ).c_str() ) );
v.push_back( a );
}
}
exec( &v );
}
private:
void exec( vector< pair<float, float> >* v )
{
int cnt = 0; bool found; float r;
while( cnt < limit )
{
cout << cnt << " : " << start << "\n";
cnt++;
vector< pair<float, float> >::iterator it = v->begin();
found = false;
while( it != v->end() )
{
r = start * ( ( *it ).first / ( *it ).second );
if( r == floor( r ) )
{
found = true;
break;
}
++it;
}
if( found ) start = ( int )r;
else break;
}
}
int start, limit;
};
int main( int argc, char* argv[] )
{
fractran f; f.run( "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", 2, 15 );
return system( "pause" );
}

View file

@ -0,0 +1,65 @@
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
typedef struct frac_s *frac;
struct frac_s {
int n, d;
frac next;
};
frac parse(char *s)
{
int offset = 0;
struct frac_s h = {0}, *p = &h;
while (2 == sscanf(s, "%d/%d%n", &h.n, &h.d, &offset)) {
s += offset;
p = p->next = malloc(sizeof *p);
*p = h;
p->next = 0;
}
return h.next;
}
int run(int v, char *s)
{
frac n, p = parse(s);
mpz_t val;
mpz_init_set_ui(val, v);
loop: n = p;
if (mpz_popcount(val) == 1)
gmp_printf("\n[2^%d = %Zd]", mpz_scan1(val, 0), val);
else
gmp_printf(" %Zd", val);
for (n = p; n; n = n->next) {
// assuming the fractions are not reducible
if (!mpz_divisible_ui_p(val, n->d)) continue;
mpz_divexact_ui(val, val, n->d);
mpz_mul_ui(val, val, n->n);
goto loop;
}
gmp_printf("\nhalt: %Zd has no divisors\n", val);
mpz_clear(val);
while (p) {
n = p->next;
free(p);
p = n;
}
return 0;
}
int main(void)
{
run(2, "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");
return 0;
}

View file

@ -0,0 +1,21 @@
(defun fractran (n frac-list)
(lambda ()
(prog1
n
(when n
(let ((f (find-if (lambda (frac)
(integerp (* n frac)))
frac-list)))
(when f (setf n (* f n))))))))
;; test
(defvar *primes-ft* '(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))
(loop with fractran-instance = (fractran 2 *primes-ft*)
repeat 20
for next = (funcall fractran-instance)
until (null next)
do (print next))

View file

@ -0,0 +1,18 @@
import std.stdio, std.algorithm, std.conv, std.array;
void fractran(in string prog, int val, in uint limit) {
const fracts = prog.split.map!(p => p.split("/").to!(int[])).array;
foreach (immutable n; 0 .. limit) {
writeln(n, ": ", val);
const found = fracts.find!(p => val % p[1] == 0);
if (found.empty)
break;
val = found.front[0] * val / found.front[1];
}
}
void main() {
fractran("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", 2, 15);
}

View file

@ -0,0 +1,26 @@
import std.stdio, std.algorithm, std.conv, std.array, std.range;
struct Fractran {
int front;
bool empty = false;
const int[][] fracts;
this(in string prog, in int val) {
this.front = val;
fracts = prog.split.map!(p => p.split("/").to!(int[])).array;
}
void popFront() {
const found = fracts.find!(p => front % p[1] == 0);
if (found.empty)
empty = true;
else
front = found.front[0] * front / found.front[1];
}
}
void main() {
Fractran("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", 2)
.take(15).writeln;
}

View file

@ -0,0 +1,62 @@
package main
import (
"fmt"
"log"
"math/big"
"os"
"strconv"
"strings"
)
func compile(src string) ([]big.Rat, bool) {
s := strings.Fields(src)
r := make([]big.Rat, len(s))
for i, s1 := range s {
if _, ok := r[i].SetString(s1); !ok {
return nil, false
}
}
return r, true
}
func exec(p []big.Rat, n *big.Int, limit int) {
var q, r big.Int
rule:
for i := 0; i < limit; i++ {
fmt.Printf("%d ", n)
for j := range p {
q.QuoRem(n, p[j].Denom(), &r)
if r.BitLen() == 0 {
n.Mul(&q, p[j].Num())
continue rule
}
}
break
}
fmt.Println()
}
func usage() {
log.Fatal("usage: ft <limit> <n> <prog>")
}
func main() {
if len(os.Args) != 4 {
usage()
}
limit, err := strconv.Atoi(os.Args[1])
if err != nil {
usage()
}
var n big.Int
_, ok := n.SetString(os.Args[2], 10)
if !ok {
usage()
}
p, ok := compile(os.Args[3])
if !ok {
usage()
}
exec(p, &n, limit)
}

View file

@ -0,0 +1,35 @@
package main
import (
"fmt"
"log"
"math/big"
"os"
"os/exec"
)
func main() {
c := exec.Command("ft", "1000000", "2", `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`)
c.Stderr = os.Stderr
r, err := c.StdoutPipe()
if err != nil {
log.Fatal(err)
}
if err = c.Start(); err != nil {
log.Fatal(err)
}
var n big.Int
for primes := 0; primes < 20; {
if _, err = fmt.Fscan(r, &n); err != nil {
log.Fatal(err)
}
l := n.BitLen() - 1
n.SetBit(&n, l, 0)
if n.BitLen() == 0 && l > 1 {
fmt.Printf("%d ", l)
primes++
}
}
fmt.Println()
}

View file

@ -0,0 +1,12 @@
import Data.List (find)
import Data.Ratio (Ratio, (%), denominator)
fractran :: (Integral a) => [Ratio a] -> a -> [a]
fractran fracts n = n :
case find (\f -> n `mod` denominator f == 0) fracts of
Nothing -> []
Just f -> fractran fracts $ truncate (fromIntegral n * f)
main :: IO ()
main = print $ take 15 $ fractran [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] 2

View file

@ -0,0 +1,27 @@
record fract(n,d)
procedure main(A)
fractran("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", 2)
end
procedure fractran(s, n, limit)
execute(parse(s),n, limit)
end
procedure parse(s)
f := []
s ? while not pos(0) do {
tab(upto(' ')|0) ? put(f,fract(tab(upto('/')), (move(1),tab(0))))
move(1)
}
return f
end
procedure execute(f,d,limit)
/limit := 15
every !limit do {
if d := (d%f[i := !*f].d == 0, (writes(" ",d)/f[i].d)*f[i].n) then {}
else break write()
}
write()
end

View file

@ -0,0 +1,2 @@
toFrac=: '/r' 0&".@charsub ] NB. read fractions from string
fractran15=: ({~ (= <.) i. 1:)@(toFrac@[ * ]) ^:(<15) NB. return first 15 Fractran results

View file

@ -0,0 +1,3 @@
taskstr=: '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'
taskstr fractran15 2
2 15 825 725 1925 2275 425 390 330 290 770 910 170 156 132

View file

@ -0,0 +1,54 @@
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Fractran{
public static void main(String []args){
new Fractran("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", 2);
}
final int limit = 15;
Vector<Integer> num = new Vector<>();
Vector<Integer> den = new Vector<>();
public Fractran(String prog, Integer val){
compile(prog);
dump();
exec(2);
}
void compile(String prog){
Pattern regexp = Pattern.compile("\\s*(\\d*)\\s*\\/\\s*(\\d*)\\s*(.*)");
Matcher matcher = regexp.matcher(prog);
while(matcher.find()){
num.add(Integer.parseInt(matcher.group(1)));
den.add(Integer.parseInt(matcher.group(2)));
matcher = regexp.matcher(matcher.group(3));
}
}
void exec(Integer val){
int n = 0;
while(val != null && n<limit){
System.out.println(n+": "+val);
val = step(val);
n++;
}
}
Integer step(int val){
int i=0;
while(i<den.size() && val%den.get(i) != 0) i++;
if(i<den.size())
return num.get(i)*val/den.get(i);
return null;
}
void dump(){
for(int i=0; i<den.size(); i++)
System.out.print(num.get(i)+"/"+den.get(i)+" ");
System.out.println();
}
}

View file

@ -0,0 +1,39 @@
var num = new Array();
var den = new Array();
var val ;
function compile(prog){
var regex = /\s*(\d*)\s*\/\s*(\d*)\s*(.*)/m;
while(regex.test(prog)){
num.push(regex.exec(prog)[1]);
den.push(regex.exec(prog)[2]);
prog = regex.exec(prog)[3];
}
}
function dump(prog){
for(var i=0; i<num.length; i++)
document.body.innerHTML += num[i]+"/"+den[i]+" ";
document.body.innerHTML += "<br>";
}
function step(val){
var i=0;
while(i<den.length && val%den[i] != 0) i++;
return num[i]*val/den[i];
}
function exec(val){
var i = 0;
while(val && i<limit){
document.body.innerHTML += i+": "+val+"<br>";
val = step(val);
i ++;
}
}
// Main
compile("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");
dump();
var limit = 15;
exec(2);

View file

@ -0,0 +1,15 @@
fractionlist = {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};
n = 2;
steplimit = 20;
j = 0;
break = False;
While[break == False && j <= steplimit,
newlist = n fractionlist;
isintegerlist = IntegerQ[#] & /@ newlist;
truepositions = Position[isintegerlist, True];
If[Length[truepositions] == 0,
break = True,
Print[ToString[j] <> ": " <> ToString[n]];
n = newlist[[truepositions[[1, 1]]]]; j++;
]
]

View file

@ -0,0 +1,6 @@
sub ft (\n) {
first Int, map (* * n).narrow,
<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>, 0
}
constant FT = 2, &ft ... 0;
say FT[^100];

View file

@ -0,0 +1,6 @@
constant FT2 = FT.grep: { not $_ +& ($_ - 1) }
for 1..* -> $i {
given FT2[$i] {
say $i, "\t", .msb, "\t", $_;
}
}

View file

@ -0,0 +1,31 @@
use strict;
use warnings;
use Math::BigRat;
my ($n, @P) = map Math::BigRat->new($_), qw{
2 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
};
$|=1;
MAIN: for( 1 .. 5000 ) {
print " " if $_ > 1;
my ($pow, $rest) = (0, $n->copy);
until( $rest->is_odd ) {
++$pow;
$rest->bdiv(2);
}
if( $rest->is_one ) {
print "2**$pow";
} else {
#print $n;
}
for my $f_i (@P) {
my $nf_i = $n * $f_i;
next unless $nf_i->is_int;
$n = $nf_i;
next MAIN;
}
last;
}
print "\n";

View file

@ -0,0 +1,21 @@
from fractions import Fraction
def fractran(n, fstring='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'):
flist = [Fraction(f) for f in fstring.replace(' ', '').split(',')]
n = Fraction(n)
while True:
yield n.numerator
for f in flist:
if (n * f).denominator == 1:
break
else:
break
n *= f
if __name__ == '__main__':
n, m = 2, 15
print('First %i members of fractran(%i):\n ' % (m, n) +
', '.join(str(f) for f,i in zip(fractran(n), range(m))))

View file

@ -0,0 +1,13 @@
from fractran import fractran
def fractran_primes():
for i, fr in enumerate(fractran(2), 1):
binstr = bin(fr)[2:]
if binstr.count('1') == 1:
prime = binstr.count('0')
if prime > 1: # Skip 2**0 and 2**1
yield prime, i
if __name__ == '__main__':
for (prime, i), j in zip(fractran_primes(), range(15)):
print("Generated prime %2i from the %6i'th member of the fractran series" % (prime, i))

1
Task/Fractran/README Normal file
View file

@ -0,0 +1 @@
Data source: http://rosettacode.org/wiki/Fractran

View file

@ -0,0 +1,23 @@
/*REXX pgm runs FRACTRAN for a given set of fractions and from a given N*/
numeric digits 999 /*be able to handle larger nums. */
parse arg N terms fracs /*get optional arguments from CL.*/
if N=='' | N==',' then N=2 /*N specified? No, use default.*/
if terms==''|terms==',' then terms=100 /*TERMS specified? Use default.*/
if fracs='' then fracs= , /*any fractions specified? No···*/
'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'
f=space(fracs,0) /* [↑] use default for fractions.*/
do i=1 while f\==''; parse var f n.i '/' d.i ',' f
end /*i*/ /* [↑] parse all the fractions.*/
#=i-1 /*the number of fractions found. */
say # 'fractions:' fracs /*display # and actual fractions.*/
say 'N is starting at ' N /*display the starting number N.*/
say terms ' terms are being shown:' /*display a kind of header/title.*/
do j=1 for terms /*perform loop once for each term*/
do k=1 for #; if N//d.k\==0 then iterate /*not an integer?*/
say right('term' j,35) ' ' N /*display the Nth term with N. */
N = N % d.k * n.k /*calculate the next term (use %)*/
leave /*go start calculating next term.*/
end /*k*/ /* [↑] if integer, found a new N*/
end /*j*/
/*stick a fork in it, we're done.*/

View file

@ -0,0 +1,35 @@
/*REXX pgm runs FRACTRAN for a given set of fractions and from a given N*/
numeric digits 999; w=length(digits()) /*be able to handle larger nums. */
parse arg N terms fracs /*get optional arguments from CL.*/
if N=='' | N==',' then N=2 /*N specified? No, use default.*/
if terms==''|terms==',' then terms=100 /*TERMS specified? Use default.*/
if fracs='' then fracs= , /*any fractions specified? No···*/
'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'
f=space(fracs,0) /* [↑] use default for fractions.*/
L=length(N) /*length in decimal digits of N.*/
tell= terms>0 /*flag: show # or a power of 2.*/
do i=1 while f\==''; parse var f n.i '/' d.i ',' f
end /*i*/ /* [↑] parse all the fractions.*/
!.=0 /*default value for powers of 2.*/
if \tell then do p=0 until length(_)>digits(); _=2**p; !._=1
if p<2 then @._=left('',w+9) '2**'left(p,w) " "
else @._='(prime' right(p,w)") 2**"left(p,w) ' '
end /*p*/ /* [↑] build powers of 2 tables.*/
#=i-1 /*the number of fractions found. */
say # 'fractions:' fracs /*display # and actual fractions.*/
say 'N is starting at ' N /*display the starting number N.*/
if tell then say terms ' terms are being shown:' /*display hdr.*/
else say 'only powers of two are being shown:' /* " " */
q='(max digits used: ' /*a literal used in the SAY below*/
do j=1 for abs(terms) /*perform loop once for each term*/
do k=1 for #; if N//d.k\==0 then iterate /*not an integer?*/
if tell then say right('term' j,35) ' ' N /*display Nth term&N*/
else if !.N then say right('term' j,15) '' @.N q,
right(L,w)") " N /*2ⁿ.*/
N = N % d.k * n.k /*calculate the next term (use %)*/
L=max(L, length(N)) /*maximum number of decimal digs.*/
leave /*go start calculating next term.*/
end /*k*/ /* [↑] if integer, found a new N*/
end /*j*/
/*stick a fork in it, we're done.*/

View file

@ -0,0 +1,31 @@
#lang racket
(define (displaysp x)
(display x)
(display " "))
(define (read-string-list str)
(map string->number
(string-split (string-replace str " " "") ",")))
(define (eval-fractran n list)
(for/or ([e (in-list list)])
(let ([en (* e n)])
(and (integer? en) en))))
(define (show-fractran fr n s)
(printf "First ~a members of fractran(~a):\n" s n)
(displaysp n)
(for/fold ([n n]) ([i (in-range (- s 1))])
(let ([new-n (eval-fractran n fr)])
(displaysp new-n)
new-n))
(void))
(define fractran
(read-string-list
(string-append "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")))
(show-fractran fractran 2 15)

View file

@ -0,0 +1,18 @@
str ="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"
FractalProgram = str.split(',').map(&:to_r) #=> array of rationals
Runner = Enumerator.new do |y|
num = 2
loop{ y << num *= FractalProgram.detect{|f| (num*f).denominator == 1} }
end
prime_generator = Enumerator.new do |y|
Runner.each do |num|
l = Math.log2(num)
y << l.to_i if l.floor == l
end
end
# demo
p Runner.take(20)
p prime_generator.take(20)

View file

@ -0,0 +1,36 @@
$ include "seed7_05.s7i";
include "rational.s7i";
const func array integer: fractran (in integer: limit, in var integer: number, in array rational: program) is func
result
var array integer: output is 0 times 0;
local
var integer: index is 1;
var rational: newNumber is 0/1;
begin
output := [] (number);
while index <= length(program) and length(output) <= limit do
newNumber := rat(number) * program[index];
if newNumber = rat(trunc(newNumber)) then
number := trunc(newNumber);
output &:= number;
index := 1;
else
incr(index);
end if;
end while;
end func;
const proc: main is func
local
const array rational: program is []
(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);
var array integer: output is 0 times 0;
var integer: number is 0;
begin
output := fractran(15, 2, program);
for number range output do
write(number <& " ");
end for;
writeln;
end func;

View file

@ -0,0 +1,29 @@
$ include "seed7_05.s7i";
include "bigrat.s7i";
const proc: fractran (in var bigInteger: number, in array bigRational: program) is func
local
var integer: index is 1;
var bigRational: newNumber is 0_/1_;
begin
while index <= length(program) do
newNumber := rat(number) * program[index];
if newNumber = rat(trunc(newNumber)) then
number := trunc(newNumber);
if 2_ ** ord(log2(number)) = number then
writeln(log2(number));
end if;
index := 1;
else
incr(index);
end if;
end while;
end func;
const proc: main is func
local
const array bigRational: program is []
(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_);
begin
fractran(2_, program);
end func;

View file

@ -0,0 +1,49 @@
package require Tcl 8.6
oo::class create Fractran {
variable fracs nco
constructor {fractions} {
set fracs {}
foreach frac $fractions {
if {[regexp {^(\d+)/(\d+),?$} $frac -> num denom]} {
lappend fracs $num $denom
} else {
return -code error "$frac is not a supported fraction"
}
}
if {![llength $fracs]} {
return -code error "need at least one fraction"
}
}
method execute {n {steps 15}} {
set co [coroutine [incr nco] my Generate $n]
for {set i 0} {$i < $steps} {incr i} {
lappend result [$co]
}
catch {rename $co ""}
return $result
}
method Step {n} {
foreach {num den} $fracs {
if {$n % $den} continue
return [expr {$n * $num / $den}]
}
return -code break
}
method Generate {n} {
yield [info coroutine]
while 1 {
yield $n
set n [my Step $n]
}
return -code break
}
}
set ft [Fractran new {
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
}]
puts [$ft execute 2]

View file

@ -0,0 +1,12 @@
oo::objdefine $ft method pow2 {n} {
set co [coroutine [incr nco] my Generate 2]
set pows {}
while {[llength $pows] < $n} {
set item [$co]
if {($item & ($item-1)) == 0} {
lappend pows $item
}
}
return $pows
}
puts [$ft pow2 10]