Mathdice Computer
Warning, the program is still buggy!
Please mail me with any bugs you find.
Known Bugs
- Factorials are not implemented. Suggest these be allowed for non-negative integers.
- Repeating decimals are not implemented.
- "X Y Z root pow" and "X Z Y neg root root" are always the same. Is this sufficiently different visually to be considered mathematically equivalent?
- Distribution of square roots: "X Y prod_???_x sqrt" is the same as "X sqrt Y sqrt prod_???_x"
Fixed Bugs
- The program wasn't doing negatives and square roots of powers and roots.
- The program didn't know to put a decimal place before a 1 (this is because
I wrote the check as "greater than 1" and not "greater than or equal to 1".)
- The program had problems with operator precedence causing duplication.
For example, any expression of the form ((W p X) q (Y r Z)), where WXYZ are
numbers and pqr are operators, appeared twice, because you could either do
p before r, or you could do p after r.
- Final values are now rounded to the nearest integer if they are less than
0.000001 away from it. Values that created rounding are marked with
the term "[rounded]" in the output, as a warning that this might not be
exact. Even expressions as simple as (2+5)/(.8-.7) were becoming
69.9999999999.
- Integer exponents less than 50 are now expanded by a series of
multiplications (or divisions if the exponent is negative > -50).
- Instead of refusing to multiply and divide by negated expressions,
the new behavior is that the program refuses to multiply by negative
values.
- When the number flies towards infinity (because of large exponent towers),
the program would sometimes result in blank outputs because of inability
to compare numbers with infinity for sorting purposes. This has now been
fixed.
- The program previously was finicky with negative bases for exponents
and roots, effectively refusing to consider them at all. The current
behavior is to allow them, but only when the exponent is integral.
WILL-NOT-FIX Bugs
- If the "original numbers" are distinct, they will not be considered
mathematically equivalent. For example, "48/3" and "4.8/.3" are not
the same, "27+8" and "28+7" are not the same. This is because the
calculations are under completely different branches, and there's no
good way to detect them.
- One small exception to the above is that if there is a division, and
all involved numbers are primitive numbers < 1, then it will be
ignored. For example, ".8/.2" will not be considered. If you can
provide other such simplifications that don't depend on knowing other
numbers, I'll try to accommodate.
- When the base of an exponent or root is negative, only integral
powers will be considered (see above). If
the exponent is supposed to be integral but isn't because of computing
imprecision (see 69.999999999 above), too bad.
- No equivalence based on sign changes of bases will be implemented;
it's just too messy when non-integer exponents are involved. Yes,
it's obvious that (7-5)^2 and (5-7)^2 are the same, but
(7-5)^1.99999 is well-defined, while (5-7)^1.99999 is a mess.
Documentation
The basic assumptions I've made are as follows:
- The feeder numbers are all non-zero single digits. I think
the program will work for 0, as well as integers greater than
9, but I haven't really tested it.
- The four standard operations are allowed.
- Division by zero is not allowed.
- parentheses (arbitrary order of operations) is allowed.
- Unary minus (negation) is allowed.
- exponentiation is allowed. 0^0 is defined as 0 for convenience.
- named roots are allowed. For example, with a 3, you can make
a cube root. Probably of more controversy is whether expressions
are allowed there -- for example, if you have a 5 and a 2, can you
make a cube root as well, by putting "5 - 2" above the radical.
Also, this means that you can also put a 2 above the radical
for a square root (see next point).
- unnamed roots are allowed; this means that you get an arbitrary
square root. To avoid infinite square root explosion in the search,
the first parameter is an integer that tells you how many layers of
square roots are you allowed per term. Of course, the more this
number is, the more computationally expensive it is.
The general scheme of the algorithm is that I put together all combinations
of the terms, with no regards as to integers, and then filter the resulting
list by integer outcomes.
For one sample output to look at, click here..
That tells you integers you can make with the digits 3, 4, and 8, using
no more than 1 layer of square roots per term.
I've done many, many revisions of the algorithm, trying to remove
expressions that are "mathematically equivalent." More on that later.
The notation for the formula is post-fix, which means that the numbers
come first,
then the operators. For example, if X, Y, and Z are numbers, and + and * are
binary operators, then "X Y Z + *" is what we would think of as X * (Y+Z).
The operators I have are:
"neg" : unary operator. - Takes the additive inverse of the previous number.
"sqrt" : unary operator.
- Takes the square root of the previous number.
Note that the number of successive sqrt operators that can be taken
is limited -- the first digit in the filename is the maximum number of
sqrt operations that can be used.
"sum2+" : binary operator.
- Sums the two previous numbers.
"sum3+" : trinary operator.
- Sums the three previous numbers.
"sumN+" : multinary operator.
- same as above, see pattern.
"prod_nn_x" : binary operator.
- Takes the product of two previous numbers.
"prod_nd_x" : binary operator.
- Takes the ratio of the two previous numbers;
the first one is the numerator, the second one is the denominator.
"prod_dn_x" : binary operator.
- Takes the ratio of the two previous numbers;
the first one is the denominator, the second one is the numerator.
"prod_nnn_x" : trinary operator.
- Takes the product of three previous numbers.
"prod_nnd_x", "prod_ndn_x", "prod_dnn_x", "prod_ndd_x", etc.:
- same as
above, see pattern.
"pow": binary operator.
- "X Y pow" means "raise X to the Yth power".
"root": binary operator.
- "X Y root" means "take the Yth root of X".
Concatenation and decimal point operations do not have operators, since
they can only apply at the number level.
For example, let me take the program's output for "making 16 with the digits
3, 4, and 8," and express them in more readable infix form:
16 (12 ways)
= 0.3 4.8 prod_dn_x
= 0.3 neg 0.8 sum2+ 4 neg pow
= 3 48 prod_dn_x
= 4 0.3 neg 0.8 sum2+ root
= 4 3 pow sqrt 8 sum2+
= 4 8 3 neg root root
= 4 8 3 root pow
= 4 sqrt 3 pow 8 sum2+
= 8 0.3 root 4 prod_nd_x sqrt
= 8 3 4 prod_dn_x pow
= 8 3 pow 4 sqrt prod_nd_x sqrt
= 8 sqrt 0.3 root 4 sqrt prod_nd_x
= 8 sqrt 3 pow 4 sqrt sqrt prod_nd_x
As you can see, some of these are still mathematically equivalent -- the program isn't perfect yet :)
Existing Files
Request Computation