Title: | A 'FRACTRAN' Interpreter and Some Helper Functions |
---|---|
Description: | 'FRACTRAN' is an obscure yet tantalizing programming language invented by John Conway of 'Game of Life' fame. The code consists of a sequence of fractions. The rules are simple. First, select an integer to initialize the process. Second, multiply the integer by the first fraction. If an integer results, start again with the new integer. If not, try the next fraction. Finally, if no such multiplication yields an integer, terminate the program. For more information, see <https://en.wikipedia.org/wiki/FRACTRAN> . |
Authors: | Carl Witthoft [aut, cre] |
Maintainer: | Carl Witthoft <[email protected]> |
License: | LGPL-3 |
Version: | 1.0.1 |
Built: | 2024-11-29 08:42:35 UTC |
Source: | CRAN |
'FRACTRAN' is an obscure yet tantalizing programming language invented by John Conway of 'Game of Life' fame. The code consists of a sequence of fractions. The rules are simple. First, select an integer to initialize the process. Second, multiply the integer by the first fraction. If an integer results, start again with the new integer. If not, try the next fraction. Finally, if no such multiplication yields an integer, terminate the program. For more information, see <https://en.wikipedia.org/wiki/FRACTRAN> .
The DESCRIPTION file:
Package: | Rfractran |
Type: | Package |
Title: | A 'FRACTRAN' Interpreter and Some Helper Functions |
Version: | 1.0.1 |
Date: | 2023-08-28 |
Authors@R: | c(person(given = "Carl", family = "Witthoft", role = c("aut","cre"), email= "[email protected]")) |
Depends: | gmp |
Description: | 'FRACTRAN' is an obscure yet tantalizing programming language invented by John Conway of 'Game of Life' fame. The code consists of a sequence of fractions. The rules are simple. First, select an integer to initialize the process. Second, multiply the integer by the first fraction. If an integer results, start again with the new integer. If not, try the next fraction. Finally, if no such multiplication yields an integer, terminate the program. For more information, see <https://en.wikipedia.org/wiki/FRACTRAN> . |
License: | LGPL-3 |
NeedsCompilation: | no |
Packaged: | 2023-08-28 15:13:40 UTC; cgw |
Author: | Carl Witthoft [aut, cre] |
Maintainer: | Carl Witthoft <[email protected]> |
Repository: | CRAN |
Date/Publication: | 2023-08-29 16:30:18 UTC |
Config/pak/sysreqs: | libgmp3-dev |
Index of help topics:
Rfractran-package A 'FRACTRAN' Interpreter and Some Helper Functions fracAns A Q&D "Logulator" to Find Numbers of Interest From 'fracDo' Output fracDo The FRACTRAN Interpreter Function fracMake Function to Create a Sequence of 'bigq' Fractions stopPrime Function to Stop 'fracDo' When Finding Primes
FRACTRAN is an obscure yet tantalizing programming "language" invented by John Conway of "Game of Life" fame. The code consists of a sequence of fractions. The operation is simple. 1 - Initalize with an integer 2 - Multiply the integer by the first fraction. If an integer results, start again with the new integer. If not, try the next fraction. 3 - If no such multiplication yields an integer, terminate the program. One warning: there is a FRACTRAN program that can be found on the web which is supposed to generate the digits of pi. Unfortunately, it's known to have a bug which causes it not to work. So far nobody has found a correction for it.
Carl Witthoft [aut, cre] Maintainer: Carl Witthoft <[email protected]>
https://esolangs.org/wiki/Fractran https://oeis.org/wiki/List_of_FRACTRAN_programs_to_compute_core_sequences
##Not Run # addition: { 3/2 } . Enter 2^a*3^b and get 3^(a+b) answer when terminated # multiplication: # { 455/33, 11/13, 1/11, 3/7, 11/2, 1/3 } # then enter 2^a*3^b Terminates with 5^(a*b) # prime generator (This function never terminates.) #start with 10, feed to [7/3 99/98 13/49 39/35 36/91 10/143 49/13 7/11 1/2 91/1] # and whenever the result of a run is of the form 10^p , p is prime
##Not Run # addition: { 3/2 } . Enter 2^a*3^b and get 3^(a+b) answer when terminated # multiplication: # { 455/33, 11/13, 1/11, 3/7, 11/2, 1/3 } # then enter 2^a*3^b Terminates with 5^(a*b) # prime generator (This function never terminates.) #start with 10, feed to [7/3 99/98 13/49 39/35 36/91 10/143 49/13 7/11 1/2 91/1] # and whenever the result of a run is of the form 10^p , p is prime
fracDo
Output
In nearly all cases FRACTRAN's "result" is the exponent of some number. This function takes the logarithm of the specified base and identifies values which are integers (or nearly so, to the specified precision).
fracAns(intvec, logbase, logprec = 1e-05)
fracAns(intvec, logbase, logprec = 1e-05)
intvec |
A vector of |
logbase |
The base of the desired logarithm, e.g. 2 or 10 in many cases. |
logprec |
A reasonably small value used to check whether the returned double should be considered to be an integer (thus ignoring binary precision errors) |
A vector of the integer values found
Carl Witthoft <[email protected]>
##---The prime generator doesn't terminate, so look for values. #start with 10, and result includes a series of values 10^p , p prime fracp10 <- fracMake(c(7,99,13,39,36,10,49,7,1,91), c(3,98,49,35,91,143,13,11,2,1)) p10 <-fracDo(10,fractions = fracp10, tries = 1000) foundp10 <-fracAns(p10,logbase = 10) # [1] 1 2 3 5 7 # sorry about the "1" :-)
##---The prime generator doesn't terminate, so look for values. #start with 10, and result includes a series of values 10^p , p prime fracp10 <- fracMake(c(7,99,13,39,36,10,49,7,1,91), c(3,98,49,35,91,143,13,11,2,1)) p10 <-fracDo(10,fractions = fracp10, tries = 1000) foundp10 <-fracAns(p10,logbase = 10) # [1] 1 2 3 5 7 # sorry about the "1" :-)
This implements the FRACTRAN process, to wit For the first fraction f in the list for which nf is an integer, replace n by nf. Repeat this rule until no fraction in the list produces an integer when multiplied by n, then halt.
fracDo(input, fractions = NULL, nums, denoms, tries = 100, stopFun = NULL, liveUpdate = TRUE, ...)
fracDo(input, fractions = NULL, nums, denoms, tries = 100, stopFun = NULL, liveUpdate = TRUE, ...)
input |
The starting integer for the given FRACTRAN code (fraction sequence) |
fractions |
The sequence of fractions. Must be in |
nums |
Vector of integers (or |
denoms |
Vector of integers (or |
tries |
A 'safety' limiter on the number of times to process the next integer generated. This avoids possible infinite runs or other time-wasters. |
stopFun |
Optional user-supplied function that can be used to terminate a FRACTRAN run early, or to take mid-run actions such as sending information to the console. See Details for more information. |
liveUpdate |
If set to TRUE, a few dots and words are sent to the console to indicate that the algorithm is still running. |
... |
Possible additional arguments for |
Some FRACTRAN programs do not terminate, most famously the prime generators.
If a specific value is being looked for, an appropriate stopFun
can be supplied to check for that value. stopFun
must return a
single logical value (R, as always will convert numerics to logical if
necessary) indicating success as TRUE. The first argument
to stopFun
must accept a single bigq
value.
If there are more arguments, they must be entered after all named
arguments. Note that this function does not have to send TRUE; it could be
used solely to execute other commands mid-run.
See stopPrime
for one such example.
A vector of all the bigq
values generated.
These all have denominator == 1, as they are the integers found in
each iteration of the FRACTRAN algorithm.
Carl Witthoft <[email protected]
https://esolangs.org/wiki/Fractran https://oeis.org/wiki/List_of_FRACTRAN_programs_to_compute_core_sequences
# addition: { 3/2 } . enter 2^a*3^b and get 3^(a+b) answer when terminated addit <- fracDo(2^5*3^8,nums = 3, denoms = 2) # Last value returned is what we want. But can't take log(bigq) log(numerator(addit[length(addit)]),3)
# addition: { 3/2 } . enter 2^a*3^b and get 3^(a+b) answer when terminated addit <- fracDo(2^5*3^8,nums = 3, denoms = 2) # Last value returned is what we want. But can't take log(bigq) log(numerator(addit[length(addit)]),3)
bigq
Fractions
Feed this function a collection of numerator and denominator values;
get a vector of bigq
fractions suitable for use as a FRACTRAN program.
fracMake(n, d = NULL)
fracMake(n, d = NULL)
n |
Vector of integers to be used as numerators, or a Nx2 array of integers
where each row contains a num, denom pair. If this is an arry, the input
|
d |
Vector of integers to be used as denominators. Ignored if |
Vector of bigq
fractions.
Carl Witthoft <[email protected]>
fracDo
When Finding Primes
This function is designed to be fed to fracDo
as the argument
stopFun
. It will send a note to the console every time a prime number
is found. It also serves as a sample of what a "stopping function" could
look like - notice that despite the name, this function doesn't
force-stop fracDo
.
stopPrime(x, mantissa,returnVal = 0)
stopPrime(x, mantissa,returnVal = 0)
x |
The current integer generated with the FRACTRAN generator ( |
mantissa |
Choose the mantissa based on the prime-generating algorithm selected.
Must be an added argument to |
returnVal |
Normally set to zero so as not to terminate
the FRACTRAN program. If desired, set to one (or TRUE) to terminate
after the first prime is found. Must be an added argument to |
There are two well-known prime generators for FRACTRAN, one of which uses
powers of two and the other uses powers of 10. Select the mantissa to match
one of these, or potentially any other FRACTRAN program which returns
values as (mantissa)^(result) . When running fracDo
, you must
enter the value as an argument after all named arguments. Similarly, if
desired, enter a value for returnVal
to fracDo
.
Returns the specified value of returnVal
so that fracDo
will or will not terminate. Its "useful" output is cat-ed to the console.
Carl Witthoft <[email protected]>
##---The prime generator doesn't terminate, so look for values. #start with 10, and result includes a series of values 10^p , p prime fracp10 <- fracMake(c(7,99,13,39,36,10,49,7,1,91), c(3,98,49,35,91,143,13,11,2,1)) p10 <-fracDo(10,fractions = fracp10, tries = 1000,stopFun=stopPrime, mantissa = 10 ) # primes found are sent to console # p10 contains all integers found.
##---The prime generator doesn't terminate, so look for values. #start with 10, and result includes a series of values 10^p , p prime fracp10 <- fracMake(c(7,99,13,39,36,10,49,7,1,91), c(3,98,49,35,91,143,13,11,2,1)) p10 <-fracDo(10,fractions = fracp10, tries = 1000,stopFun=stopPrime, mantissa = 10 ) # primes found are sent to console # p10 contains all integers found.