How to resolve the algorithm Fractran step by step in the Erlang programming language
How to resolve the algorithm Fractran step by step in the Erlang programming language
Table of Contents
Problem Statement
FRACTRAN is a Turing-complete esoteric programming language invented by the mathematician John Horton Conway. A FRACTRAN program is an ordered list of positive fractions
P
(
f
1
,
f
2
, … ,
f
m
)
{\displaystyle P=(f_{1},f_{2},\ldots ,f_{m})}
, together with an initial positive integer input
n
{\displaystyle n}
.
The program is run by updating the integer
n
{\displaystyle n}
as follows:
Conway gave a program for primes in FRACTRAN: Starting with
n
2
{\displaystyle n=2}
, this FRACTRAN program will change
n
{\displaystyle n}
to
15
2 × ( 15
/
2 )
{\displaystyle 15=2\times (15/2)}
, then
825
15 × ( 55
/
1 )
{\displaystyle 825=15\times (55/1)}
, generating the following sequence of integers: After 2, this sequence contains the following powers of 2: which are the prime powers of 2.
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 steps is limited (by a parameter easy to find).
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:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Fractran step by step in the Erlang programming language
Source code in the erlang programming language
#! /usr/bin/escript
-mode(native).
-import(lists, [map/2, reverse/1]).
binary_to_ratio(B) ->
{match, [_, Num, Den]} = re:run(B, "([0-9]+)/([0-9]+)"),
{binary_to_integer(binary:part(B, Num)),
binary_to_integer(binary:part(B, Den))}.
load(Program) ->
map(fun binary_to_ratio/1, re:split(Program, "[ ]+")).
step(_, []) -> halt;
step(N, [F|Fs]) ->
{P, Q} = mulrat(F, {N, 1}),
case Q of
1 -> P;
_ -> step(N, Fs)
end.
exec(K, N, Program) -> reverse(exec(K - 1, N, fun (_) -> true end, Program, [N])).
exec(K, N, Pred, Program) -> reverse(exec(K - 1, N, Pred, Program, [N])).
exec(0, _, _, _, Steps) -> Steps;
exec(K, N, Pred, Program, Steps) ->
case step(N, Program) of
halt -> Steps;
M -> case Pred(M) of
true -> exec(K - 1, M, Pred, Program, [M|Steps]);
false -> exec(K, M, Pred, Program, Steps)
end
end.
is_pow2(N) -> N band (N - 1) =:= 0.
lowbit(N) -> lowbit(N, 0).
lowbit(N, K) ->
case N band 1 of
0 -> lowbit(N bsr 1, K + 1);
1 -> K
end.
main(_) ->
PrimeGen = load("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"),
io:format("The first few states of the Fractran prime automaton are: ~p~n~n", [exec(20, 2, PrimeGen)]),
io:format("The first few primes are: ~p~n", [tl(map(fun lowbit/1, exec(26, 2, fun is_pow2/1, PrimeGen)))]).
% rational multiplication
mulrat({A, B}, {C, D}) ->
{P, Q} = {A*C, B*D},
G = gcd(P, Q),
{P div G, Q div G}.
gcd(A, 0) -> A;
gcd(A, B) -> gcd(B, A rem B).
You may also check:How to resolve the algorithm Show ASCII table step by step in the FutureBasic programming language
You may also check:How to resolve the algorithm Semordnilap step by step in the Lasso programming language
You may also check:How to resolve the algorithm Halt and catch fire step by step in the 6502 Assembly programming language
You may also check:How to resolve the algorithm Random number generator (device) step by step in the Ring programming language
You may also check:How to resolve the algorithm Pascal matrix generation step by step in the Delphi programming language