A Partridge In A Pear Tree

December 23, 2016

You all know the old song:

On the first day of Christmas my true love gave to me a partridge in a pear tree.

On the second day of Christmas my true love gave to me two turtle doves and a partridge in a pear tree.

On the third day of Christmas my true love gave to me three French hens, two turtle doves and a partridge in a pear tree.

On the fourth day of Christmas my true love gave to me four calling birds, three French hens, two turtle doves and a partridge in a pear tree.

On the fifth day of Christmas my true love gave to me five golden rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.

On the sixth day of Christmas my true love gave to me six geese a-laying, five golden rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.

On the seventh day of Christmas my true love gave to me seven swans a-swimming, six geese a-laying, five golden rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.

On the eighth day of Christmas my true love gave to me eight maids a-milking, seven swans a-swimming, six geese a-laying, five golden rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.

On the ninth day of Christmas my true love gave to me nine ladies dancing, eight maids a-milking, seven swans a-swimming, six geese a-laying, five golden rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.

On the tenth day of Christmas my true love gave to me ten lords a-leaping, nine ladies dancing, eight maids a-milking, seven swans a-swimming, six geese a-laying, five golden rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.

On the eleventh day of Christmas my true love gave to me eleven pipers piping, ten lords a-leaping, nine ladies dancing, eight maids a-milking, seven swans a-swimming, six geese a-laying, five golden rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.

On the twelfth day of Christmas my true love gave to me twelve drummers drumming, eleven pipers piping, ten lords a-leaping, nine ladies dancing, eight maids a-milking, seven swans a-swimming, six geese a-laying, five golden rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.

Your task is to write a program that prints the words of the song, as economically as possible. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Advertisement

Pages: 1 2

10 Responses to “A Partridge In A Pear Tree”

  1. Paul said

    I wish you a Merry Christmas and a Happy New Year.

    txtsa = [("first", "a partridge in a pear tree"),
            ("second", "two turtle doves"),
            ("third", "three French hens"),
            ("fourth", "four calling birds"),
            ("fifth", "five golden rings") ,
            ("sixth", "six geese a-laying"),
            ("seventh", "seven swans a-swimming"),
            ("eighth", "eight maids a-milking"),
            ("ninth",  "nine ladies dancing"),
            ("tenth", "ten lords a-leaping"),
            ("eleventh",  "eleven pipers piping"),
            ("twelfth", "twelve drummers drumming")
            ]
    
    cnts, txts = list(zip(*txtsa))
    
    def xmas():
        t1 = "On the {} day of Christmas my true love gave to me {}."
        print(t1.format(cnts[0], txts[0]))
        for r, cnt in enumerate(cnts[1:], 1):
            T1 = ", ".join(txts[r:0:-1]) + " and " + txts[0]
            print(t1.format(cnt, T1))
    
  2. 425 character in Common Lisp:

    
    cl-user> (ls :l)
    -        425 Dec 23 19:54 partridge.lisp
    -       2374 Dec 23 19:50 partridge.txt
    -        476 Dec 23 19:27 partridge.txt.bz2
    ; No value
    cl-user> (cat "partridge.lisp")
    (loop with w ='("partridge in a pear tree""turtle doves""French hens""calling birds""golder rings""geese a-laying""swans a-swimming""maids a-milking""ladies dancing""lords a-leaping""pipers piping""drummers drumming")with s ="."for n from 1 to 12 do(format t"~%On the ~:R day of Christmas my true love gave to me "n)(setf s(format()"~:[,~; and~] ~A"(= n 1)(write-line(setf s(format()"~:[~R~;~*a~] ~A~A"(= n 1)n(pop w)s))))))
    ; No value
    cl-user> (load "partridge.lisp")
    
    On the first day of Christmas my true love gave to me a partridge in a pear tree.
    
    On the second day of Christmas my true love gave to me two turtle doves and a partridge in a pear tree.
    
    On the third day of Christmas my true love gave to me three French hens, two turtle doves and a partridge in a pear tree.
    
    On the fourth day of Christmas my true love gave to me four calling birds, three French hens, two turtle doves and a partridge in a pear tree.
    
    On the fifth day of Christmas my true love gave to me five golder rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.
    
    On the sixth day of Christmas my true love gave to me six geese a-laying, five golder rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.
    
    On the seventh day of Christmas my true love gave to me seven swans a-swimming, six geese a-laying, five golder rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.
    
    On the eighth day of Christmas my true love gave to me eight maids a-milking, seven swans a-swimming, six geese a-laying, five golder rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.
    
    On the ninth day of Christmas my true love gave to me nine ladies dancing, eight maids a-milking, seven swans a-swimming, six geese a-laying, five golder rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.
    
    On the tenth day of Christmas my true love gave to me ten lords a-leaping, nine ladies dancing, eight maids a-milking, seven swans a-swimming, six geese a-laying, five golder rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.
    
    On the eleventh day of Christmas my true love gave to me eleven pipers piping, ten lords a-leaping, nine ladies dancing, eight maids a-milking, seven swans a-swimming, six geese a-laying, five golder rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.
    
    On the twelfth day of Christmas my true love gave to me twelve drummers drumming, eleven pipers piping, ten lords a-leaping, nine ladies dancing, eight maids a-milking, seven swans a-swimming, six geese a-laying, five golder rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.
    #P"/Users/pjb/tmp/misc/partridge.lisp"
    cl-user> 
    
  3. Oops, sorry, the bzip2 -9 file is actually only 429 bytes:

    -        429 Dec 23 20:12 partridge.bz2
    -        425 Dec 23 19:54 partridge.lisp
    -        831 Dec 23 19:59 partridge.py
    -       2374 Dec 23 19:50 partridge.txt
    
  4. matthew said

    Here’s a little C program (there are a couple of Obfuscated C competition programs that are worth a look). Not quite as short as Pascal’s (hard to compete with a language with built-in printing of numbers as ordinals):

    #include <stdio.h>
    #define L(d,n) \
      printf("On the "#d" day of Christmas my true love sent to me %s", \
             "twelve drummers drumming, eleven pipers piping, ten lords a-leaping, " \
             "nine ladies dancing, eight maids a-milking, seven swans a-swimming, " \
             "six geese a-laying, five golden rings, four calling birds, three French " \
             "hens, two turtle doves and a partridge in a pear tree\n"+n);
    int main(){
      L(first,236)L(second,215)L(third,196)L(fourth,176)
      L(fifth,157)L(sixth,137)L(seventh,113)L(eighth,90)
      L(ninth,69)L(tenth,48)L(eleventh,26)L(twelfth,0)
    }
    
  5. matthew said

    Here’s some JS as well:

    ["first","second","third","fourth","fifth","sixth",
     "seventh","eighth","ninth","tenth","eleventh","twelfth"]
        .map((d,i)=>
             console.log("On the " + d +
                         " day of Christmas my true love gave to me " +
                         ["twelve drummers drumming, ","eleven pipers piping, ",
                          "ten lords a-leaping, ","nine ladies dancing, ",
                          "eight maids a-milking, ","seven swans a-swimming, ",
                          "six geese a-laying, ","five golden rings, ",
                          "four calling birds, ","three French hens, ",
                          "two turtle doves and ","a partridge in a pear tree"]
                         .slice(11-i).join("")))
    

    Merry Christmas all.

  6. Steve Graham said

    Here’s the 12 days in MUMPS:
    twelvedays ;
    n i,j,nth
    f i=1:1:12 d
    . s nth=$p($t(days),”;”,i+1)
    . w !,”On the “,nth,” day of Christmas my true love gave to me”
    . f j=i:-1:1 d
    . . w ” ”
    . . w $p($t(presents+j),”;”,2)
    . . i j>2 w “,”
    . . e w $s(j=2:” and”,1:”.”)
    q
    ;
    days ;first;second;third;fourth;fifth;sixth;seventh;eighth;ninth;tenth;eleventh;twelfth
    presents ;
    ;a partridge in a pear tree
    ;two turtle doves
    ;three French hens
    ;four calling birds
    ;five golden 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

  7. I thought I would try in Python:


    gifts = {
        'twelvth': 'twelve drummers drumming',
        'eleventh': 'eleven pipers piping',
        'tenth': 'ten lords a-leaping',
        'ninth': 'nine ladies dancing',
        'eighth': 'eight maids a-milking',
        'seventh': 'seven swans a-swimming',
        'sixth': 'six geese a-laying',
        'fifth': 'five golden rings',
        'fourth': 'four calling birds',
        'third': 'three French hens',
        'second': 'two turtle doves and ',
        'first': 'a partridge in a pear tree.',
    }
    days = ('first', 'second', 'third', 'fourth', 'fifth', 'sixth',
            'seventh', 'eighth', 'ninth', 'tenth', 'eleventh', 'twelvth')

    def first_part(day):
        print("On the {} day of Christmas"
              " my true love gave to me ".format(day), end="")

    def second_part(gift, comma=True):
        print(gift, end="")
        print(end=", ") if comma else None

    for day in days:
        first_part(day)
        for i in range(days.index(day), -1, -1):
            comma = False if (i == 0 or i == 1) else True
            gift = gifts[days[i]]
            second_part(gift, comma)
        print()

  8. Actually, I quite like the obfuscated C version, and it is easy to de-obfuscate:

    (let ((p “On the ~:r day of Christmas my true love gave to me ~a~%”)
    (r “twelve drummers drumming, eleven pipers piping, ten lords a-leaping, nine ladies dancing, eight maids a-milking, seven swans a-swimming, six geese a-laying, five golden rings, four calling birds, three French hens, two turtle doves and a partridge in a pear tree.”))
    (let loop ((i ‘(236 215 196 176 157 137 113 90 69 48 26 0))
    (c 1))
    (if (not (null? i))
    (begin
    (format #t p c (substring r (car i)))
    (loop (cdr i) (+ c 1))))))

    But a constructive version could also make use of format, although its dsl is very unschemely:

    (let ((p “On the ~:r day of Christmas my true love gave to me ~a~%”))
    (let loop ((r ‘(“turtle doves” “French hens” “calling birds” “golden rings”
    “geese a-laying” “swans a-swimming” “maids a-milking”
    “ladies dancing” “lords a-leaping” “pipers piping” “drummers drumming”))
    (s “a partridge in a pear tree.”)
    (c 1))
    (format #t p c s)
    (if (not (null? r))
    (begin
    (loop (cdr r)
    (format #f “~r ~a~a ~a” (+ c 1) (car r) (if (= c 1) ” and” “,”) s)
    (+ c 1))))))

  9. matthew said

    @Michael: Thanks, I wasn’t particularly intending to be obfuscated, just compact. For real C obfuscation see, eg: http://www.ioccc.org/1988/phillipps.c

  10. matthew said

    That program does actually print out The Twelve Days of Christmas, if it’s not clear from the code.

    Happy New Year to all.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: