A Partridge In A Pear Tree
December 23, 2016
We first define the gifts, then iterate through the verses of the song in two nested loops:
(define gifts '(
("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")))
(define (christmas)
(let loop ((gifts gifts) (rev-gifts (list)))
(when (pair? gifts)
(display "On the ") (display (caar gifts))
(display " day of Christmas my true love gave to me ")
(display (cadar gifts))
(let rev-loop ((rev-gifts rev-gifts))
(when (pair? rev-gifts)
(display (if (< 1 (length rev-gifts)) ", " " and "))
(display (cadar rev-gifts))
(rev-loop (cdr rev-gifts))))
(display ".") (newline)
(loop (cdr gifts) (cons (car gifts) rev-gifts)))))
You can run the program at http://ideone.com/CRygWv.
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))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>Oops, sorry, the bzip2 -9 file is actually only 429 bytes:
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) }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.
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
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()
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))))))
@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
That program does actually print out The Twelve Days of Christmas, if it’s not clear from the code.
Happy New Year to all.