I was hoping to find an elegant solution to this riddle, using only a line or two of Mathematica:
Santa Claus was telling one of his elves: "If I multiply the age of three of my reindeer, I get 2450. If I add them up, I get the height of the Christmas tree in front of our house. Can you tell me how old the reindeer are?” After the elf went outside and measured the height of the Christmas tree, he came back and complained: “I’m sorry, but I don’t know the solution”. Santa Claus replies: “Oh, I’m sorry, I forgot to tell you that the oldest Reindeer is still younger than me.”
The question is: “How old is Santa Claus?”
My solution involved finding the following steps:
- Find unordered factorizations of 2450 using code from Mma Journal, returning a list of lists of factorizations (these do not include 1 as a factor)
- Keep only factorizations of 3 or fewer terms, and padding the shorter ones with 1's if necessary, e.g. 2450 = 2450*1*1 = 490*5*1 = 25*14*7 ...
- Testing for duplicates within the sum of these triples, using GatherBy code I found locally (because the elf would only be confused if two triples added to the same thing)
- Take the first duplicate triple, which has the smallest max age of the three reindeer, because our factorizations came out arranged in increasing order of the first factor which is also the largest of each triple
- Print out the triple along with Santa's age (oldest reindeer + 1, which I believe to be the only appropriate interpretation of the question)
My code below has the virtues of being inelegant, longer than it probably needs to be, and hard to understand. Can anyone improve on it in one or more of these categories?
UnorderedFactorizations[m_, 1] = {{}};
UnorderedFactorizations[1, n_] = {{}};
UnorderedFactorizations[m_, n_ /; PrimeQ[n]] := If[m < n, {}, {{n}}]
UnorderedFactorizations[m_, n_] := Flatten[Function[d,
Prepend[#, d] & /@ UnorderedFactorizations[d, n/d]] /@
Rest[Select[Divisors[n], # <= m &]], 1]
UnorderedFactorizations[n_] := UnorderedFactorizations[n, n]
Function[la, StringForm[
"Santa's reindeer are ages ``, ``, and ``, and he himself is age \
``.", la[[1]], la[[2]], la[[3]], la[[1]] + 1]]@
Part[#, Flatten[
Select[GatherBy[Range@Length[#], Function[n, #[[n, 1]]]],
Function[l, Length[l] >= 2]]][[1]], 2] & @
(Function[
triples, {Total[triples], triples}] /@
Function[f, PadRight[f, 3, 1]] /@
Select[UnorderedFactorizations[2450],
Function[l, Length[l] <= 3]])
Out[6] = Santa's reindeer are ages 49, 10, and 5, and he himself is age 50.
EDIT: Some more explanation. There are many combinations of 3 factors that produce 2450, but only two of them have the same sum, namely 64: (49, 10, 5) and (50, 7, 7). The elf requires additional information, namely the fact that the oldest reindeer is younger than Santa. In other words, the oldest one is 49 and Santa must be 50. I hard-coded the 1-increment to the reindeer's age, which is perhaps not very general but I also think it is correct based on a strict reading of the riddle. For example, if the second triple were (51, X, Y), then Santa's age wouldn't be uniquely determined. So even without seeing the triples, we know that one must be (R1, R2, R3) and the other (R1+1, R4, R5).
Reduce[x1 x2 x3 == 2450 && 30 > x1 >= x2 >= x3 > 0, {x1, x2, x3}, Integers]
(caribou lifespan is approx. 20 years in captivity so we require age less than 30, if we assume that the units are years). This gives a single result of ages 7, 14, and 25, which makes the tree have a height of 46 and Santa is older than 25. $\endgroup$ – Oleksandr R. Dec 12 '14 at 3:04