Perl.
use Lingua::EN::Numbers qw(num2en_ordinal);
print 'On the ', num2en_ordinal($_+1),' day of Christmas my true love gave to me, ', reverse(( split /\|/, "a partridge in a pear tree.\n|two turtle doves, and |three french hens, |four calling birds, |five gold rings, |six geese a-laying, |seven swans a-swimming, |eight maids a-milking, |nine ladies dancing, |ten lords a leaping, |eleven pipers piping, |twelve drummers drumming, ")[ 0 .. $_ ]) for 0 .. 11;
( 459 Chars )
I wanted to make it a bit nicer and expressive, but this is a golf challenge.
This style violates proper coding standards somewhat. But that's golf for you.
Lingua::EN::Number
Here's the less compact version with less sneaky tricks.
use Lingua::EN::Numbers qw(num2en_ordinal);
my @gifts = (
'a partridge in a pear tree.',
'two turtle doves, and ',
'three french hens, ',
'four calling birds, ',
'five gold rings, ',
'six geese a-laying, ',
'seven swans a-swimming, ',
'eight maids a-milking, ',
'nine ladies dancing, ',
'ten lords a leaping, ',
'eleven pipers piping, ',
'twelve drummers drumming, '
);
for my $verse_id ( 0 .. $#gifts ) {
printf 'On the %s day of Christmas my true love gave to me, ', num2en_ordinal($verse_id +1);
print reverse @verse[ 0 .. $verse_id ];
print "\n";
}