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:
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.
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:
The simplest FRACTRAN program is a single instruction such as
This program can be represented as a (very simple) algorithm as follows:
FRACTRAN instruction | Condition | Action |
---|---|---|
v2 > 0 | Subtract 1 from v2 Add 1 to v3 | |
v2 = 0 | Stop |
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.
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 state | Condition | Action | Next state |
---|---|---|---|
A | v7 > 0 | Subtract 1 from v7 Add 1 to v3 | A |
v7 = 0 and v2 > 0 | Subtract 1 from v2 | B | |
v7 = 0 and v2 = 0 and v3 > 0 | Subtract 1 from v3 | A | |
v7 = 0 and v2 = 0 and v3 = 0 | Stop | ||
B | v3 > 0 | Subtract 1 from v3 Add 1 to v5 Add 1 to v7 | B |
v3 = 0 | None | A |
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 state | State indicators | Condition | Action | Next state |
---|---|---|---|---|---|
A | None | v7 > 0 | Subtract 1 from v7 Add 1 to v3 | A | |
v7 = 0 and v2 > 0 | Subtract 1 from v2 | B | |||
v7 = 0 and v2 = 0 and v3 > 0 | Subtract 1 from v3 | A | |||
v7 = 0 and v2 = 0 and v3 = 0 | Stop | ||||
B | v11, v13 | v3 > 0 | Subtract 1 from v3 Add 1 to v5 Add 1 to v7 | B | |
v3 = 0 | None | A |
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]
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 state | State indicators | Condition | Action | Next state |
---|---|---|---|---|---|
A | v11, v13 | v2 > 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 v3 | X | |||
v3 = 0 | Add 1 to v5 | B | |||
B | v17, v19 | v7 > 0 | Subtract 1 from v7 Add 1 to v3 | B | |
v7 = 0 | None | A | |||
X | v3 > 0 | Subtract 1 from v3 | X | ||
v3 = 0 | Stop |
Writing out the FRACTRAN program, we have:
and input 2n3d11 produces output 5q7r where n = qd + r and 0 ≤ r < d.
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.
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 state | State indicators | Condition | Action | Next state |
---|---|---|---|---|---|
A | v5, v11 | v2 > 1 | Subtract 2 from v2 Add 1 to v3 | A | |
v2 = 1 | Subtract 1 from v2 Add 1 to v13 | B | |||
v2 = 0 | None | B | |||
B | None | v3 > 0 | Subtract 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 |
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.
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.
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(a, b), 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.
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.
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.
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.
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 r2 ≡ n, where p is a prime: that is, to find a square root of n modulo p.
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.