FRACTRAN

Last updated

FRACTRAN is a Turing-complete esoteric programming language invented by the mathematician John Conway. A FRACTRAN program is an ordered list of positive fractions together with an initial positive integer input n. The program is run by updating the integer n as follows:

Contents

  1. for the first fraction f in the list for which nf is an integer, replace n by nf
  2. repeat this rule until no fraction in the list produces an integer when multiplied by n, then halt.

Conway 1987 gives the following FRACTRAN program, called PRIMEGAME, which finds successive prime numbers:

Starting with n=2, this FRACTRAN program generates the following sequence of integers:

After 2, this sequence contains the following powers of 2:

(sequence A034785 in the OEIS)

The exponent part of these powers of two are primes, 2, 3, 5, etc.

Understanding a FRACTRAN program

A FRACTRAN program can be seen as a type of register machine where the registers are stored in prime exponents in the argument n.

Using Gödel numbering, a positive integer n can encode an arbitrary number of arbitrarily large positive integer variables. [note 1] The value of each variable is encoded as the exponent of a prime number in the prime factorization of the integer. For example, the integer

represents a register state in which one variable (which we will call v2) holds the value 2 and two other variables (v3 and v5) hold the value 1. All other variables hold the value 0.

A FRACTRAN program is an ordered list of positive fractions. Each fraction represents an instruction that tests one or more variables, represented by the prime factors of its denominator. For example:

tests v2 and v5. If and , then it subtracts 2 from v2 and 1 from v5 and adds 1 to v3 and 1 to v7. For example:

Since the FRACTRAN program is just a list of fractions, these test-decrement-increment instructions are the only allowed instructions in the FRACTRAN language. In addition the following restrictions apply:

Creating simple programs

Addition

The simplest FRACTRAN program is a single instruction such as

This program can be represented as a (very simple) algorithm as follows:

FRACTRAN
instruction
ConditionAction
v2 > 0Subtract 1 from v2
Add 1 to v3
v2 = 0Stop

Given an initial input of the form , this program will compute the sequence , , etc., until eventually, after steps, no factors of 2 remain and the product with no longer yields an integer; the machine then stops with a final output of . It therefore adds two integers together.

Multiplication

We can create a "multiplier" by "looping" through the "adder". In order to do this we need to introduce states into our algorithm. This algorithm will take a number and produce :

Current stateConditionActionNext state
Av7 > 0Subtract 1 from v7
Add 1 to v3
A
v7 = 0 and
v2 > 0
Subtract 1 from v2B
v7 = 0 and
v2 = 0 and
v3 > 0
Subtract 1 from v3A
v7 = 0 and
v2 = 0 and
v3 = 0
Stop
Bv3 > 0Subtract 1 from v3
Add 1 to v5
Add 1 to v7
B
v3 = 0NoneA

State B is a loop that adds v3 to v5 and also moves v3 to v7, and state A is an outer control loop that repeats the loop in state B v2 times. State A also restores the value of v3 from v7 after the loop in state B has completed.

We can implement states using new variables as state indicators. The state indicators for state B will be v11 and v13. Note that we require two state control indicators for one loop; a primary flag (v11) and a secondary flag (v13). Because each indicator is consumed whenever it is tested, we need a secondary indicator to say "continue in the current state"; this secondary indicator is swapped back to the primary indicator in the next instruction, and the loop continues.

Adding FRACTRAN state indicators and instructions to the multiplication algorithm table, we have:

FRACTRAN
instruction
Current stateState
indicators
ConditionActionNext state
ANonev7 > 0Subtract 1 from v7
Add 1 to v3
A
v7 = 0 and
v2 > 0
Subtract 1 from v2B
v7 = 0 and
v2 = 0 and
v3 > 0
Subtract 1 from v3A
v7 = 0 and
v2 = 0 and
v3 = 0
Stop
Bv11, v13v3 > 0Subtract 1 from v3
Add 1 to v5
Add 1 to v7
B
v3 = 0NoneA

When we write out the FRACTRAN instructions, we must put the state A instructions last, because state A has no state indicators - it is the default state if no state indicators are set. So as a FRACTRAN program, the multiplier becomes:

With input 2a3b this program produces output 5ab. [note 2]

The above FRACTRAN program, computing 3 times 2 (so that its input is
2
3
x
3
2
=
72
{\displaystyle 2^{3}\times 3^{2}=72}
and its output should be
5
6
{\displaystyle 5^{6}}
because 3 times 2 equals 6. FRACTRANmult0.gif
The above FRACTRAN program, computing 3 times 2 (so that its input is and its output should be because 3 times 2 equals 6.

Subtraction and division

In a similar way, we can create a FRACTRAN "subtractor", and repeated subtractions allow us to create a "quotient and remainder" algorithm as follows:

FRACTRAN
instruction
Current stateState
indicators
ConditionActionNext state
Av11, v13v2 > 0 and
v3 > 0
Subtract 1 from v2
Subtract 1 from v3
Add 1 to v7
A
v2 = 0 and
v3 > 0
Subtract 1 from v3X
v3 = 0Add 1 to v5B
Bv17, v19v7 > 0Subtract 1 from v7
Add 1 to v3
B
v7 = 0NoneA
Xv3 > 0Subtract 1 from v3X
v3 = 0Stop

Writing out the FRACTRAN program, we have:

and input 2n3d11 produces output 5q7r where n = qd + r and 0 ≤ r < d.

Conway's prime algorithm

Conway's prime generating algorithm above is essentially a quotient and remainder algorithm within two loops. Given input of the form where 0 ≤ m < n, the algorithm tries to divide n+1 by each number from n down to 1, until it finds the largest number k that is a divisor of n+1. It then returns 2n+1 7k-1 and repeats. The only times that the sequence of state numbers generated by the algorithm produces a power of 2 is when k is 1 (so that the exponent of 7 is 0), which only occurs if the exponent of 2 is a prime. A step-by-step explanation of Conway's algorithm can be found in Havil (2007).

For this program, reaching the prime number 2, 3, 5, 7... requires respectively 19, 69, 281, 710,... steps (sequence A007547 in the OEIS ).

A variant of Conway's program also exists, [1] which differs from the above version by two fractions:

This variant is a little faster: reaching 2, 3, 5, 7... takes it 19, 69, 280, 707... steps (sequence A007546 in the OEIS ). A single iteration of this program, checking a particular number N for primeness, takes the following number of steps:

where is the largest integer divisor of N and is the floor function. [2]

In 1999, Devin Kilminster demonstrated a shorter, ten-instruction program: [3]

For the initial input n = 10 successive primes are generated by subsequent powers of 10.

Other examples

The following FRACTRAN program:

calculates the Hamming weight H(a) of the binary expansion of a i.e. the number of 1s in the binary expansion of a. [4] Given input 2a, its output is 13H(a). The program can be analysed as follows:

FRACTRAN
instruction
Current stateState
indicators
ConditionActionNext state
Av5, v11v2 > 1Subtract 2 from v2
Add 1 to v3
A
v2 = 1Subtract 1 from v2
Add 1 to v13
B
v2 = 0NoneB
BNonev3 > 0Subtract 1 from v3
Add 1 to v2
B
v3 = 0 and
v7 > 0
Subtract 1 from v7
Add 1 to v2
A
v3 = 0 and
v7 = 0 and
v2 > 0
Subtract 1 from v2
add 1 to v7
B
v2 = 0 and
v3 = 0 and
v7 = 0
Stop

Notes

  1. Gödel numbering cannot be directly used for negative integers, floating point numbers or text strings, although conventions could be adopted to represent these data types indirectly. Proposed extensions to FRACTRAN include FRACTRAN++ and Bag.
  2. A similar multiplier algorithm is described at the Esolang FRACTRAN page.

See also

Related Research Articles

<span class="mw-page-title-main">Analysis of algorithms</span> Study of resources used by an algorithm

In computer science, the analysis of algorithms is the process of finding the computational complexity of algorithms—the amount of time, storage, or other resources needed to execute them. Usually, this involves determining a function that relates the size of an algorithm's input to the number of steps it takes or the number of storage locations it uses. An algorithm is said to be efficient when this function's values are small, or grow slowly compared to a growth in the size of the input. Different inputs of the same size may cause the algorithm to have different behavior, so best, worst and average case descriptions might all be of practical interest. When not otherwise specified, the function describing the performance of an algorithm is usually an upper bound, determined from the worst case inputs to the algorithm.

<span class="mw-page-title-main">Euclidean algorithm</span> Algorithm for computing greatest common divisors

In mathematics, the Euclidean algorithm, or Euclid's algorithm, is an efficient method for computing the greatest common divisor (GCD) of two integers (numbers), the largest number that divides them both without a remainder. It is named after the ancient Greek mathematician Euclid, who first described it in his Elements . It is an example of an algorithm, a step-by-step procedure for performing a calculation according to well-defined rules, and is one of the oldest algorithms in common use. It can be used to reduce fractions to their simplest form, and is a part of many other number-theoretic and cryptographic calculations.

In mathematics, the factorial of a non-negative integer , denoted by , is the product of all positive integers less than or equal to . The factorial of also equals the product of with the next smaller factorial:

In mathematics, the greatest common divisor (GCD) of two or more integers, which are not all zero, is the largest positive integer that divides each of the integers. For two integers x, y, the greatest common divisor of x and y is denoted . For example, the GCD of 8 and 12 is 4, that is, gcd(8, 12) = 4.

<span class="mw-page-title-main">Least common multiple</span> Smallest positive number divisible by two integers

In arithmetic and number theory, the least common multiple, lowest common multiple, or smallest common multiple of two integers a and b, usually denoted by lcm(ab), is the smallest positive integer that is divisible by both a and b. Since division of integers by zero is undefined, this definition has meaning only if a and b are both different from zero. However, some authors define lcm(a, 0) as 0 for all a, since 0 is the only common multiple of a and 0.

<span class="mw-page-title-main">Multiplication</span> Arithmetical operation

Multiplication is one of the four elementary mathematical operations of arithmetic, with the other ones being addition, subtraction, and division. The result of a multiplication operation is called a product.

In computational complexity theory, the class NC (for "Nick's Class") is the set of decision problems decidable in polylogarithmic time on a parallel computer with a polynomial number of processors. In other words, a problem with input size n is in NC if there exist constants c and k such that it can be solved in time O((log n)c) using O(nk) parallel processors. Stephen Cook coined the name "Nick's class" after Nick Pippenger, who had done extensive research on circuits with polylogarithmic depth and polynomial size.

<span class="mw-page-title-main">Prime number</span> Number divisible only by 1 or itself

A prime number is a natural number greater than 1 that is not a product of two smaller natural numbers. A natural number greater than 1 that is not prime is called a composite number. For example, 5 is prime because the only ways of writing it as a product, 1 × 5 or 5 × 1, involve 5 itself. However, 4 is composite because it is a product (2 × 2) in which both numbers are smaller than 4. Primes are central in number theory because of the fundamental theorem of arithmetic: every natural number greater than 1 is either a prime itself or can be factorized as a product of primes that is unique up to their order.

Shor's algorithm is a quantum algorithm for finding the prime factors of an integer. It was developed in 1994 by the American mathematician Peter Shor. It is one of the few known quantum algorithms with compelling potential applications and strong evidence of superpolynomial speedup compared to best known classical algorithms. On the other hand, factoring numbers of practical significance requires far more qubits than available in the near future. Another concern is that noise in quantum circuits may undermine results, requiring additional qubits for quantum error correction.

In mathematics, a continued fraction is an expression obtained through an iterative process of representing a number as the sum of its integer part and the reciprocal of another number, then writing this other number as the sum of its integer part and another reciprocal, and so on. In a finite continued fraction, the iteration/recursion is terminated after finitely many steps by using an integer in lieu of another continued fraction. In contrast, an infinite continued fraction is an infinite expression. In either case, all integers in the sequence, other than the first, must be positive. The integers are called the coefficients or terms of the continued fraction.

<span class="mw-page-title-main">Egyptian fraction</span> Finite sum of distinct unit fractions

An Egyptian fraction is a finite sum of distinct unit fractions, such as

An integer programming problem is a mathematical optimization or feasibility program in which some or all of the variables are restricted to be integers. In many settings the term refers to integer linear programming (ILP), in which the objective function and the constraints are linear.

<span class="mw-page-title-main">Unit fraction</span> One over a whole number

A unit fraction is a positive fraction with one as its numerator, 1/n. It is the multiplicative inverse (reciprocal) of the denominator of the fraction, which must be a positive natural number. Examples are 1/1, 1/2, 1/3, 1/4, 1/5, etc. When an object is divided into equal parts, each part is a unit fraction of the whole.

Modular exponentiation is exponentiation performed over a modulus. It is useful in computer science, especially in the field of public-key cryptography, where it is used in both Diffie–Hellman key exchange and RSA public/private keys.

Shanks' square forms factorization is a method for integer factorization devised by Daniel Shanks as an improvement on Fermat's factorization method.

The Tonelli–Shanks algorithm is used in modular arithmetic to solve for r in a congruence of the form r2n, where p is a prime: that is, to find a square root of n modulo p.

<span class="mw-page-title-main">Linear programming relaxation</span>

In mathematics, the relaxation of a (mixed) integer linear program is the problem that arises by removing the integrality constraint of each variable.

In algebra, the greatest common divisor of two polynomials is a polynomial, of the highest possible degree, that is a factor of both the two original polynomials. This concept is analogous to the greatest common divisor of two integers.

A repeating decimal or recurring decimal is a decimal representation of a number whose digits are eventually periodic ; if this sequence consists only of zeros, the decimal is said to be terminating, and is not considered as repeating. It can be shown that a number is rational if and only if its decimal representation is repeating or terminating. For example, the decimal representation of 1/3 becomes periodic just after the decimal point, repeating the single digit "3" forever, i.e. 0.333.... A more complicated example is 3227/555, whose decimal becomes periodic at the second digit following the decimal point and then repeats the sequence "144" forever, i.e. 5.8144144144.... Another example of this is 593/53, which becomes periodic after the decimal point, repeating the 13-digit pattern "1886792452830" forever, i.e. 11.18867924528301886792452830....

Ganita Kaumudi (Gaṇitakaumudī) is a treatise on mathematics written by Indian mathematician Narayana Pandita in 1356. It was an arithmetical treatise alongside the other algebraic treatise called "Bijganita Vatamsa" by Narayana Pandit.

References

  1. Guy 1983 , p. 26; Conway & Guy 1996 , p. 147
  2. Guy 1983 , p. 33
  3. Havil 2007 , p. 176
  4. John Baez, Puzzle #4, The n-Category Café