17 October 2010

The n Days of Christmas

I love to love recursion! There, I said that I said it. It's a word that's scary to some, but fun to say. Also, as a professional programmer it's a word to drop occasionally to make yourself sound smart. "I made the function recursive thus reducing the lines of code." For your additional information this also works for algorithm, method and deprecate. Do know the meanings, however, before using.

While it is a bit early on this year, I got to thinking about the famous Twelve Days of Christmas algorithm. There is a lot of items being gifted! It becomes a little bit involved to think though just how many.

  • Day 1: 1 partridge
  • Day 2: 2 turtle doves + 1 partridge + (Day 1)
  • ...
  • Day 12: 12 pipers + 11 lords + 10 maids + .... + 1 partridge + (Day 11) + (Day 10) ... + (Day 1)

Each day's individual total gifts can be summed up with an equation.
g(n) = n + n-1 + n-2 ... + 1
The fun begins when the previous days have to be added in. H(N) = g(N) + g(N-1) .. + g(1)
The beginning programmer might be temped to solve the days of Christmas through (ugh!) hardcoding the calculations. Don't fall into this trap. The daily calculation is a simple recusive function that will give us the results.
function howManyToday(n){ return (n==1) ? n : howManyToday(n-1) + n; }
Running this function as howManyToday(2) will return the 3 items for the day (2 turtle doves + 1 partridge). While good for one day, this will not return the total. On day 2 we would also have to be including day 1's total. Nearly the same exact function can be used to wrap the daily total.
function whichDay(d) { return (d==1) ? d : howManyToday(d-1) + whichDay(d-1) + d; }
These two functions can be compressed further to make this problem even more fun to solve. The twelve days of Christmas have been a source of code obfuscation fun for a long time. This code works the same exact way but is oh so much more interesting.var _____ = 1; function _(__) {return (__==_____)?__:___(__-_____)+ _(__-_____)+__;} function ___(____){return (____==_____)?____:___(____-_____)+____;} With a call to whichDay(d) or _(__) we can find out how many items would be gifted on any day. Note to anyone who found this site by looking for basic recursion for a 101 class, avoid the ternary and avoid the obfuscation.

0 comments: