This post is about “Taxi cab numbers” specifically the “Ramanujan-Hardy number”, 1729. This specific taxi cab number is so-called because it is the smallest positive number that can be written as a sum of two cubes in two ways.
The real definition of a Taxi cab number(Wiki) T(n) is “a number that can be expressed as the sum of cubes in distinct ways”. So, given that definition, 1729 is T(2).
Worth mentioning is that according to Fermat’s last theorem, for each . This means that is a non-integer. If the theorem was false, the taxi cab numbers would not be so special, there would be lots of them. Although it seems as though the definition of a taxi cab number is restrictive, there are many solutions of which the sum of two cubes are only expressed in exactly one way for instance, as opposed to three ways of which there are very few, if any (that I know of).
The origins of the taxi cab number, 1729, comes from the Indian mathematician Srinivasa Ramanujan and Godfrey H. Hardy. As Hardy recalls:
I remember once going to see him when he (Ramanujan) was ill at Putney. I had ridden in taxi cab number 1729 and remarked that the number seemed to me rather a dull one, and that I hoped it was not an unfavorable omen. “No”, he replied, “it is a very interesting number; it is the smallest number expressible as the sum of two cubes in two different ways.”
Ok, so we can do this in a very simple way: We wish to find , where are integers. We can do this with two nested for-loops and try all a and b etc. Unfortunately, this solution is inefficient, we can do better. First of all, we don’t know the number 1729, so we have to find it using a loop. Instead of trying all and , we can use the fact that . So, we can try for instance b=1 and we get 1729-1, so a must be an integer and it should have the value 1728^(1/3).
We can do this for each b from 1 to any number num and just check which of these b giving us an integer solution to a.
In Matlab this can be achieved using a vector
b = 1:(num)^(1/3)
a = (num-b.^3).^(1/3)
We only need to check b from 1 to num^(1/3) because by inspecting the last element of b we have (num-(num^1/3)^3) which is 0 (for larger b we get complex answers).
How do we know for which a we have an integer expression?
We need to be careful, for instance
1728^(1/3) == 12^3 returns 0
We have that
1728^(1/3) is 11.999999999999998 in Matlab.
This is because of the machine accuracy for numbers. In Matlab they are by default double precision, which means we have an accuracy of ~15 decimal places, so we need to round off a little.
To be on the safe side, we round the numbers in b to 10 decimal places (digits=10) and compare with the integers, I store these in a vector cands.
cands = round(b) == round((10^digits*b))/(10^digits)
cands is now a binary vector. To get the candidates we write
terms = find(cands)
To make sure we only find 1729, we add the condition
The number of terms in cands are (ways to sum), because we have two candidates for each.
1 0 0 0 0 0 0 0 1 1 0 1
terms = find(cands)
1 9 10 12
The solutions are thus and . In order to print them, I arranged the answers using reshape and took the outer values of the vector terms and work inwards
tmp = reshape(terms, 2, length(terms)/2);
tmp(2,:) = tmp(2, end:-1:1)
Please note: We will always have an even number of elements in ‘terms’.
For this run I compute 1729, T(2), and then I continue to find the larger sums for fun. These numbers are not taxi cab numbers, because they are larger than 1729.
1^3 + 12^3 = 1729
10^3 + 9^3 = 1729
2^3 + 16^3 = 4104
15^3 + 9^3 = 4104
2^3 + 24^3 = 13832
20^3 + 18^3 = 13832
9^3 + 58^3 = 195841
57^3 + 22^3 = 195841
The code takes about 5 seconds to run with this example.