Skip to content

SINTEF Blog Gå til forsiden

  • Energy
  • Ocean
  • Digital
  • Health
  • Industry
  • Climate and environment
  • Building
  • Society
  • EN
  • NO
Digital

Python Challenge Rerun: How short can you write the python-code needed to generate the entire lyrics of “Twelve days of Christmas”?

author
Kjetil Johannessen
Research Manager
Published: 21. Dec 2018 | Last edited: 11. Apr 2025
3 min. reading
Comments (25)

This is a rerun of a Christmas favourite from last year:

Here is Christmas Special Python Challenge from SINTEF to you:

  • How short can you write the python-code needed to generate the entire lyrics of “Twelve days of Christmas”

Submit your suggestion in the comments section below.

 

  • Read more about Computational Sciences and Engineering at SINTEF

 

The twelve days of christmas. Illustration: Shutterstock
The twelve days of christmas. Illustration: Shutterstock

About Python

The Python programming language offers an intuitive syntax and good OO features. The collection of standard and 3rd party modules is comprehensive and growing. It is available on most platforms, and it is extendable and embedable. It is usable from soft RT applications to complex data analysis and Processing.

The lyrics: On the first day of Christmas my true love gave to me

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 gold 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 gold 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 gold 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 gold 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 gold 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 gold 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 gold 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 gold rings
four calling birds
three French hens
two turtle doves
and a partridge in a pear tree

 

Comments

lucasvazq says:
20. March 2022 at 20:52

(255 chars, 715 bytes)
exec(bytes(‘潦⁲⁥湩爠湡敧ㄨ⤲瀺楲瑮∨湏琠敨┠⁳慤⁹景䌠牨獩浴獡湜祍琠畲⁥潬敶猠湥⁴潴洠≥∥楆獲⁴敓潣摮吠楨摲䘠畯瑲⁨楆瑦⁨楓瑸⁨敓敶瑮⁨楅桧桴丠湩桴吠湥桴䔠敬敶瑮⁨睔汥瑦≨献汰瑩⤨敛ⱝ∪睔汥敶䐠畲浭牥⁳牄浵幭汅癥湥倠灩牥⁳楐幰敔潌摲⵳ⵡ敌灡乞湩⁥慌楤獥䐠湡幣楅桧⁴慍摩⵳ⵡ楍歬卞癥湥匠慷獮愭匭楷浭卞硩䜠敥敳愭䰭祡䙞癩⁥潇摬删湩獧簬潆牵䌠污楬杮䈠物獤簬桔敲⁥牆湥档䠠湥ⱳ呼潷吠牵汴⁥潄敶ⱳ愠摮䅼倠牡牴摩敧椠⁡敐牡吠敲⹥湜⸢敲汰捡⡥帢Ⱒ椢杮簬⤢献汰瑩∨≼嬩敾崺猬灥∽湜⤢’,’U16′)[2:])

(460 chars, 460 bytes)
for e in range(12):print(“On the %s day of Christmas\nMy true love sent to me”%”First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh Twelfth”.split()[e],*”Twelve Drummers Drumm^Eleven Pipers Pip^Ten Lords-a-Leap^Nine Ladies Danc^Eight Maids-a-Milk^Seven Swans-a-Swimm^Six Geese-a-Lay^Five Gold Rings,|Four Calling Birds,|Three French Hens,|Two Turtle Doves, and|A Partridge in a Pear Tree.\n”.replace(“^”,”ing,|”).split(“|”)[~e:],sep=”\n”)

Reply
Barry Clague says:
12. February 2021 at 16:52

I think my mod below is more ‘Pythonic’ though

#Print 12 Days of Christmas song using loops
Present_List = [‘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’]

Days = [‘first’, ‘second’, ‘third’, ‘forth’, ‘fifth’, ‘sixth’, ‘seventh’,
‘eighth’, ‘ninth’, ‘tenth’, ‘eleventh’, ‘twelfth’]

for Day_No, Day_Name in enumerate(Days):
print(‘\nOn the ‘ + Day_Name + ‘ day of Christmas my true love gave to me ‘ + Present_List[Day_No])
for Present in reversed(range(Day_No)):
print(Present_List[Present])

Reply
Barry says:
11. February 2021 at 02:44

#Print 12 Days of Christmas song using loops (my first ever Python program)

Present_List = [‘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’]

Days = [‘first’, ‘second’, ‘third’, ‘forth’, ‘fifth’, ‘sixth’, ‘seventh’,
‘eighth’, ‘ninth’, ‘tenth’, ‘eleventh’, ‘twelfth’]

for Day_No, Day_Name in enumerate(Days):
print(‘On the ‘ + Day_Name + ‘ day of Christmas my true love sent to me…’)
while Day_No >= 0:
print(‘…..’ + Present_List[Day_No])
Day_No -= 1

Reply
Jarand Røynstrand says:
21. December 2017 at 16:03

If I am alowed the inflect module, that was not part of the default Python instalation, but it easily downloaded using pip install inflect I get 476

import inflect as e
p=e.engine()
for i in range(12):print(“On the {} day of Christmas my true love gave to me\n”.format(p.number_to_words(p.ordinal(i+1)))+””.join([“twelve drummers drumming\n”,”eleven pipers piping\n”,”ten lords a-leaping\n”,”nine ladies dancing\n”,”eight maids a-milking\n”,”seven swans a-swimming\n”,”six geese a-laying\n”,”five gold rings\n”,”four calling birds\n”,”three French hens\n”,”two turtle doves\nand “,”a partridge in a pear tree\n”][11-i:]))

If I am alowed to write 1st instead of first, I do not need to call p.number_to_words() and get down to 457
If I compress that again, I get 427. (But this is with 1st, 2nd etc.)

import zlib,base64
exec(zlib.decompress(base64.b64decode(b’eJxFkc9OwzAMxu97CqunVmOVynESJySuPMDYwbRuakicyElXJsS7425sXPLn98mf4y8cUtQCLKOnvgBmoE16opbEsVDdbMaowKaDojiqu8dmn5Sl1NWrQJkIvn9gwDPEEZ4n5VyCeYQzFJ0JfDwROLSlRAj0JlVrfgFLndqoAwv6mrdd02yrqv2ILPWhKgt5Kxh0DoE0Xw8szoofKvJ0IoHEaZVsuwnFqDfLDLjzhHcuNgV4HJjMCaW/G7GbCgTkS0Vg/3lT8qVDXlBWJS/83z3zFziiTGsTPN/wyOuU0Q9gwbh8ZXFW6NF7I/DO9rDrMyclghcl6SeYSP7oEqHMWryNbYkZRBnABISEWpQHR+sX2JVQLVpaozweum7H+2PT/AITT5yx’)))

Reply
Jarand Røynstrand says:
21. December 2017 at 16:09

Sorry, I counted wrongly. The compressed version is only marginaly shorter at 456

Reply
Jarand Røynstrand says:
21. December 2017 at 16:31

On the other hand, as p is only used once, I do not need it, and cne save a few characters by incorporating the call to e.engine() into the print statement.

That brings me down to 452 with no compression.

Reply
Jarand Røynstrand says:
21. December 2017 at 11:45

The system messed up the single quotes, replae them with normal single quotes, and the code will run. e(b’eJ and ==’))
If you prefer the uncompressed version:

for i in range(12):print(“On the {} day of Christmas my true love gave to me\n”.format(“first,second,third,fourth,fifth,sixth,seventh,eighth,ninth,tenth,eleventh,twelfth”.split(“,”)[i])+””.join([“twelve drummers drumming\n”,”eleven pipers piping\n”,”ten lords a-leaping\n”,”nine ladies dancing\n”,”eight maids a-milking\n”,”seven swans a-swimming\n”,”six geese a-laying\n”,”five gold rings\n”,”four calling birds\n”,”three French hens\n”,”two turtle doves\nand “,”a partridge in a pear tree\n”][11-i:]))

Everything in one line, to avoid wasting characters on line breaks. (Yes, I know that line breakes are normally not a waste, but in this setting they are.)

Reply
Kjetil Johannessen says:
21. December 2017 at 12:57

This is impressively dense for being uncompressed. 503 characters vs 480 on your compressed version. Think you can squeeze this down below 480?

Reply
Jarand Røynstrand says:
21. December 2017 at 11:28

import zlib,base64
exec(zlib.decompress(base64.b64decode(b’eJxFUbtuwzAM/BVCU4w6BtIxa4Gu/YA0A2tRFls9DEqJGxT991Jxki6kdWc+7uiyAAMnEEwTbXbP3X4WTnVj3hJUT/DzCxYvkB28eOFSIxaIF6hyIgj5TDChhpoh0nsyg8sSUasdS6l9oTEn21fPYnuXT1J979hpLPzdIp0paSaevKbE7VFXKNy4ulDQCjOUObB27k134GP3ZMzwmTltDqb9oTtYOcVIUtYPTpPu05u1D8w8N0rTndAxKkBsAdwGwgeuS6gytEzaCdP4aNR2hIh8rYgcvu7MVQWUBVNjysL/01UmTESF2hC83GHHzbgcLKjXU1kxtQdGDEER+FDDVrh6IYJXoTR68JRu6JKhqp1BZesRFMRkQQmEGaUK24naVfVJKHotatc5Hna7Le+P0HV/Zu2xDw==’)))

Reply
Kristoffer Nyborg Gregertsen says:
21. December 2017 at 10:03

Code should be readable and maintainable:

#! /usr/bin/python3

def xmas():
lyrics = [(1, ‘a partridge in a pear tree’,’first’),
(2, ‘two turtle doves’,’second’),
(3, ‘three French hens’,’third’),
(4, ‘four calling birds’,’fourth’),
(5, ‘five gold rings’,’fifth’),
(6, ‘six geese a-laying’,’sixth’),
(7, ‘seven swans a-swimming’,’seventh’),
(8, ‘eight maids a-milking’,’eight’),
(9, ‘nine ladies dancing’,’ninth’),
(10, ‘ten lords a-leaping’,’tenth’),
(11, ‘eleven pipers piping’,’eleventh’),
(12, ‘twelve drummers drumming’,’twelfth’)]

for (i, what, day) in lyrics:
print(“On the {} of Christmas my true love gave to me”.format(day))

for j in reversed(range(0, i)):
if i > 1 and j == 0:
print(‘and ‘, end=”)
print(lyrics[j][1])

print()

if __name__ == ‘__main__’:
xmas()

Still some room for improvement. Wait for my Ada example…

Reply
Kristoffer Nyborg Gregertsen says:
21. December 2017 at 10:28

#! /usr/bin/python3

def day(i):
o = [‘first’, ‘second’, ‘third’, ‘fourth’,
‘fifth’, ‘sixth’, ‘seventh’, ‘eight’,
‘ninth’, ‘tenth’, ‘eleventh’, ‘twelfth’]
return “On the {} day of Christmas my true love gave to me”.format(o[i])

def what(i):
w = [‘a partridge in a pear tree’,
‘two turtle doves’,
‘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’]
return w[i]

def xmas():
for i in range(0, 12):
print(day(i))
for j in reversed(range(0, i+1)):
if i > 0 and j == 0:
print(‘and ‘ + what(j))
else:
print(what(j))
print()

if __name__ == ‘__main__’:
xmas()

Reply
Kjetil Johannessen says:
21. December 2017 at 12:55

+1 for readability. That is some SINTEF-quality over that piece of code!

Reply
Kristoffer Nyborg Gregertsen says:
21. December 2017 at 10:04

Formatting was messed up…

Reply
Jarand Røynstrand says:
20. December 2017 at 21:32

I have a feeling this is not a winner,but it is possible to do it in 480 characters, without depending on external sources:

import zlib,base64
exec(zlib.decompress(base64.b64decode(b’eJxFUbtuwzAM/BVCU4w6BtIxa4Gu/YA0A2tRFls9DEqJGxT991Jxki6kdWc+7uiyAAMnEEwTbXbP3X4WTnVj3hJUT/DzCxYvkB28eOFSIxaIF6hyIgj5TDChhpoh0nsyg8sSUasdS6l9oTEn21fPYnuXT1J979hpLPzdIp0paSaevKbE7VFXKNy4ulDQCjOUObB27k134GP3ZMzwmTltDqb9oTtYOcVIUtYPTpPu05u1D8w8N0rTndAxKkBsAdwGwgeuS6gytEzaCdP4aNR2hIh8rYgcvu7MVQWUBVNjysL/01UmTESF2hC83GHHzbgcLKjXU1kxtQdGDEER+FDDVrh6IYJXoTR68JRu6JKhqp1BZesRFMRkQQmEGaUK24naVfVJKHotatc5Hna7Le+P0HV/Zu2xDw==’)))

Reply
Jarand Røynstrand says:
21. December 2017 at 11:34

The system muddles my single quotes. Put in a normal single quote in b’eJxFUbt and Dw==’))) and it will run.

Reply
Jarand Røynstrand says:
20. December 2017 at 21:34

import zlib,base64
exec(zlib.decompress(base64.b64decode(b’eJxFUbtuwzAM/BVCU4w6BtIxa4Gu/YA0A2tRFls9DEqJGxT9
91Jxki6kdWc+7uiyAAMnEEwTbXbP3X4WTnVj3hJUT/DzCxYvkB28eOFSIxaIF6hyIgj5TDChhpoh0nsyg8s
SUasdS6l9oTEn21fPYnuXT1J979hpLPzdIp0paSaevKbE7VFXKNy4ulDQCjOUObB27k134GP3ZMzwmTlt
Dqb9oTtYOcVIUtYPTpPu05u1D8w8N0rTndAxKkBsAdwGwgeuS6gytEzaCdP4aNR2hIh8rYgcvu7MVQW
UBVNjysL/01UmTESF2hC83GHHzbgcLKjXU1kxtQdGDEER+FDDVrh6IYJXoTR68JRu6JKhqp1BZesRFM
RkQQmEGaUK24naVfVJKHotatc5Hna7Le+P0HV/Zu2xDw==’)))

Reply
Jarand Røynstrand says:
20. December 2017 at 21:38

Does the entire lines survive? Or do you miss out on something? I will repsot once again with shorter lines:

import zlib,base64
exec(zlib.decompress(base64.b64decode(b’eJxFUbtuwzAM/BVCU4w6BtIxa4Gu/
YA0A2tRFls9DEqJGxT991Jxki6kdWc+7uiyAAMnEEwTbXbP3X4WTnVj3hJUT/Dz
CxYvkB28eOFSIxaIF6hyIgj5TDChhpoh0nsyg8sSUasdS6l9oTEn21fPYnuXT1J97
9hpLPzdIp0paSaevKbE7VFXKNy4ulDQCjOUObB27k134GP3ZMzwmTltDqb9oT
tYOcVIUtYPTpPu05u1D8w8N0rTndAxKkBsAdwGwgeuS6gytEzaCdP4aNR2hIh8
rYgcvu7MVQWUBVNjysL/01UmTESF2hC83GHHzbgcLKjXU1kxtQdGDEER+FD
DVrh6IYJXoTR68JRu6JKhqp1BZesRFMRkQQmEGaUK24naVfVJKHotatc5Hna7
Le+P0HV/Zu2xDw==’)))

Remember: Thereshould be no line breaks in the exec string

Reply
Jarand Røynstrand says:
20. December 2017 at 19:45

If you are allowed to read from an external source, why not assume a local copy of the lyrics in a file called a?
print(open(‘a’).read())

Reply
Jarand Røynstrand says:
20. December 2017 at 19:46

23 symbols

Reply
Kjetil Johannessen says:
21. December 2017 at 12:48

I feel like this is cheating, but I appreciate the creativity 😉

Reply
Jarand Røynstrand says:
21. December 2017 at 14:28

;-P

Reply
Jo says:
20. December 2017 at 18:58

I made a solution, i dont know if this is allowed but here it is:

import bs4, requests; soup=bs4.BeautifulSoup(requests.get(“https://blog.sintef.com/digital-en/how-many-python-lines-do-you-need-to-generate-the-entire-lyrics-of-twelve-days-of-christmas/”).text, ‘lxml’)
for t in soup.find(“div”,{‘id’:’entry-content’}).findAll(“p”)[5:]:print(str(t).replace(“”, “”).replace(“”, “\n”).replace(“”, “”))

Reply
Jo says:
20. December 2017 at 18:58

344 symbols in total

Reply
Jarand Røynstrand says:
21. December 2017 at 15:16

Lose the variable soup, and you cam do it in 331 characters.

import bs4,requests
for t in bs4.BeautifulSoup etc….

Reply
Kjetil Johannessen says:
21. December 2017 at 13:03

I can’t tell why, but this feels less like cheating than reading from file. Though you can probably also find a shorter url somewhere if you are counting characters.

Reply

Leave a comment Cancel reply

Your email address will not be published. Required fields are marked *

More about Digital

Industrial worker looking at digital heatmap in front of metal forge. Created with Copilot

Agentic workflows for simulation-driven decision support

Author Image
Author Image
Author Image
3 forfattere
Smart building

Kickstart of the Nordic Smart Building Initiative

5 forfattere
CO2DataShare illustration

CO₂DataShare: Open data as a cure for a climate crisis

Author Image
Author Image
Author Image
4 forfattere

Technology for a better society

  • About this blog
  • How to write a science blog
  • Topics and collections
  • Sign up for our newsletter
  • News from NTNU and SINTEF
  • Facebook
Gå til SINTEF.no
SINTEF logo
© 2025 SINTEF Foundation
Privacy Editorial Press contacts Website by Headspin