December 10th
Chimneys
The age-old question: how does Santa fit down a chimney? Turns out he's very flexible. Santa can reshape his rotund body in an almost octopus-like manner, and can squeeze himself into the smallest of rectangular chimney stacks.
Your task is to work out the cross-sectional area of each of these chimney stacks and determine whether Santa's cross-sectional... 'area' will fit into them.
The snag is Santa appears differently in different countries. The traditional British Father Christmas was positively skinny, wore a green cloak and carried a wreath of ivy. France's Pere Noel is a bit bigger, and wears a fur-lined hood. In the Netherlands Sinterklaas is a fairly big guy wearing a red mitre. American children expect a supersized Santa Claus, so he must squeeze a much bigger version of himself into those US chimneys.
The Problem
The data is in three parts:
The belt size used by each country's Santa, eg 'S' in the UK, 'XL' in the US.
The belt codes and their size ranges (Santa always uses the largest belt size)
The list of chimneys Santa has to try to fit down.
You must work out whether the area of each chimney is enough to accept the cross-sectional area of that country's Santa. All dimensions are in cm.
DecompositionÂ
Any multi-step coding task should be broken down into individual functions that can each be tested separately. Here's a breakdown of the functions you should create to solve the task. After the data set we've included a selection of asserts to test your functions are correct. Copy these into your IDE then write your functions above them. The asserts will pass silently if your function is correct, otherwise they'll throw an error.
def belt_code(country_code) takes a country code and returns S, M, L or XL
def belt_length(belt_code) takes a belt code and returns the maximum belt length in cm
def santa_area(country_code) takes a country code and uses that country's belt as the circumference of Santa and returns that circle's area as an integer (ie discard any decimals). import math then use math.pi for π
def rectangle_area(chimney) takes a chimney size string eg '20x15' and returns its area, eg 300
def can_fit(country_code, chimney) takes a country_code and the dimensions of a chimney, returns True or False depending whether that country's Santa can fit into that chimney
def count_chimneys(chimneys) takes a list of chimneys and calls can_fit on each one. Returns how many are accessible to that country's Santa
Testing
# Unit tests for sub-functions
assert rectangle_area('10x10') == 100, 'tiny'
assert rectangle_area('20x20') == 400, 'small'
assert rectangle_area('25x25') == 625, 'medium'
assert rectangle_area('30x30') == 900, 'big'
assert belt_length('S') == 83
assert belt_length('M') == 89
assert belt_length('L') == 97
assert belt_length('XL') == 104
assert belt_code('UK') == 'S'
assert belt_code('NL') == 'L'
assert belt_code('FR') == 'M'
assert belt_code('US') == 'XL'
uk_santa_area = int((83 / 2) ** 2 / math.pi)
us_santa_area = int((104 / 2) ** 2 / math.pi)
assert santa_area('UK') == uk_santa_area
assert santa_area('US') == us_santa_area
# Integration tests
assert belt_length(belt_code('UK')) == 83
assert belt_length(belt_code('NL')) == 97
assert belt_length(belt_code('FR')) == 89
assert belt_length(belt_code('US')) == 104
assert can_fit('UK', '23x23') == False, 'UK fail'
assert can_fit('UK', '23x24') == True, 'UK pass'
assert can_fit('FR', '25x25') == False, 'FR fail'
assert can_fit('FR', '25x26') == True, 'FR pass'
assert can_fit('NL', '27x27') == False, 'NL fail'
assert can_fit('NL', '27x28') == True, 'NL pass'
assert can_fit('US', '29x29') == False, 'US fail'
assert can_fit('US', '29x30') == True, 'US pass'
assert count_chimneys(['UK 23x23', 'FR 25x25', 'NL 27x27', 'US 29x29']) == 0, 'chimneys too small'
assert count_chimneys(['UK 23x24', 'FR 25x26', 'NL 27x28', 'US 29x30']) == 4, 'chimneys just okay'
Your data sets:
# constants
BELT_SIZES = 'S:76-83cm M:84-89cm L:90-97cm XL:99-104cm'
SANTA_BELTS = [['UK', 'S'], ['FR', 'M'], ['NL', 'L'], ['US', 'XL']]
# the chimneys
chimneys = ['UK 20x31', 'UK 20x29', 'FR 29x30', 'NL 32x30', 'NL 35x27', 'FR 21x20', 'UK 35x25', 'UK 35x34', 'FR 32x26', 'US 30x26', 'US 27x31', 'NL 26x33', 'FR 32x34', 'NL 28x30', 'NL 25x26', 'UK 33x25', 'UK 30x26', 'UK 21x32', 'UK 26x29', 'UK 35x26', 'NL 35x27', 'US 21x29', 'FR 28x23', 'UK 22x24', 'FR 32x20', 'US 26x27', 'FR 33x35', 'US 21x24', 'FR 25x20', 'NL 30x28', 'UK 23x35', 'US 22x30', 'UK 28x27', 'UK 23x35', 'FR 34x35', 'UK 35x31', 'NL 22x34', 'UK 21x29', 'US 34x20', 'UK 33x26', 'FR 24x28', 'FR 28x27', 'FR 33x27', 'UK 25x30', 'FR 25x26', 'NL 30x33', 'FR 27x32', 'US 33x22', 'US 29x32', 'NL 24x26', 'FR 24x33', 'NL 25x26', 'NL 29x34', 'FR 33x26', 'US 28x32', 'UK 29x35', 'US 31x30', 'US 32x27', 'FR 27x34', 'NL 33x33', 'FR 33x21', 'FR 34x20', 'NL 23x26', 'NL 35x31', 'UK 22x21', 'US 21x21', 'US 24x20', 'NL 20x21', 'US 28x21', 'UK 26x34', 'FR 33x26', 'NL 27x24', 'UK 32x23', 'FR 31x23', 'NL 30x24', 'UK 26x24', 'US 35x23', 'FR 34x35', 'NL 25x28', 'NL 22x23', 'FR 31x22', 'FR 29x28', 'UK 28x27', 'NL 30x30', 'FR 21x25', 'UK 27x33', 'NL 30x28', 'FR 29x23', 'US 24x32', 'US 28x25', 'UK 24x25', 'US 28x30', 'UK 26x34', 'FR 30x20', 'FR 31x34', 'US 24x28', 'FR 27x28', 'FR 27x30', 'FR 28x21', 'FR 21x29', 'US 25x23', 'FR 33x30', 'FR 26x21', 'NL 27x32', 'NL 28x33', 'FR 32x22', 'US 34x32', 'FR 33x28', 'NL 26x29', 'NL 29x28', 'UK 26x20', 'FR 27x35', 'UK 25x25', 'US 33x20', 'NL 34x24', 'US 24x21', 'UK 20x27', 'UK 24x29', 'FR 29x21', 'NL 23x29', 'US 26x28', 'NL 24x33', 'NL 28x27', 'NL 24x28', 'US 34x34', 'UK 24x31', 'FR 31x32', 'US 28x23', 'UK 21x22', 'FR 28x20', 'UK 29x24', 'US 30x34', 'FR 30x22', 'NL 28x31', 'US 20x28', 'NL 28x25', 'UK 33x23', 'US 21x29', 'NL 27x34', 'US 35x33', 'NL 33x23', 'FR 35x35', 'UK 30x31', 'NL 27x29', 'FR 35x29', 'NL 34x25', 'UK 26x27', 'US 21x22', 'FR 33x27', 'NL 25x22', 'UK 28x34', 'UK 20x27', 'US 33x30', 'UK 24x20', 'US 26x33', 'UK 25x24', 'UK 32x20', 'FR 28x24', 'UK 32x35', 'FR 25x25', 'FR 23x28', 'FR 30x24', 'NL 29x33', 'US 24x29', 'UK 22x34', 'UK 35x35', 'NL 26x31', 'NL 34x21', 'NL 26x24', 'US 23x21', 'FR 35x22', 'UK 34x28', 'FR 24x28', 'US 32x27', 'UK 35x29', 'US 27x28', 'UK 24x21', 'NL 21x35', 'FR 24x33', 'FR 25x25', 'UK 35x23', 'NL 24x20', 'UK 23x21', 'NL 35x23', 'NL 23x28', 'FR 24x21', 'NL 30x31', 'UK 21x31', 'US 26x27', 'UK 26x20', 'FR 29x22', 'UK 34x26', 'NL 30x29', 'NL 33x28', 'NL 24x30', 'NL 26x23', 'US 31x29', 'US 35x35', 'UK 27x35', 'NL 25x27', 'UK 28x20', 'UK 20x29', 'UK 35x26', 'US 22x35', 'FR 26x27', 'UK 23x21', 'FR 33x26', 'NL 34x32', 'US 23x29', 'US 27x33', 'FR 28x26', 'NL 30x27', 'UK 24x30', 'UK 26x22', 'NL 25x29', 'FR 30x24', 'FR 28x35', 'US 29x32', 'US 30x25', 'UK 22x26', 'FR 20x34', 'FR 29x32', 'FR 22x20', 'FR 20x23', 'UK 20x28', 'UK 35x30', 'US 28x24', 'US 22x29', 'US 21x23', 'FR 32x31', 'UK 31x27', 'FR 30x34', 'NL 25x35', 'US 33x33', 'NL 26x23', 'UK 28x23', 'FR 33x27', 'UK 24x25', 'US 20x28', 'US 35x34', 'US 27x34', 'UK 33x30', 'NL 26x33', 'US 31x23', 'NL 28x31', 'UK 30x23', 'FR 27x24', 'US 35x27', 'US 27x21', 'US 21x23', 'NL 27x28', 'NL 34x32', 'NL 34x34', 'NL 31x23', 'NL 25x21', 'UK 27x25', 'US 32x21', 'FR 22x33', 'NL 26x35', 'US 32x27', 'FR 29x33', 'US 24x31', 'NL 24x21', 'FR 22x28', 'FR 29x26', 'US 21x26', 'NL 31x22', 'US 32x33', 'UK 28x28', 'NL 31x29', 'US 22x20', 'UK 35x30', 'UK 31x31', 'US 33x26', 'US 33x26', 'NL 21x24', 'US 20x24', 'NL 22x28', 'NL 24x20', 'US 26x33', 'FR 32x23', 'US 28x35', 'FR 35x28', 'UK 25x28', 'FR 22x26', 'FR 25x27', 'UK 25x28', 'UK 31x34', 'US 33x20', 'NL 28x27', 'US 22x35', 'FR 24x21', 'US 20x29', 'US 23x35', 'FR 32x29', 'UK 21x31', 'US 31x29', 'FR 27x20', 'FR 21x29', 'UK 30x22', 'NL 24x22', 'US 26x30', 'FR 33x26', 'UK 34x28', 'FR 33x32', 'NL 22x34', 'NL 32x20', 'NL 31x31', 'US 31x28', 'FR 27x35', 'NL 33x28', 'NL 20x28', 'US 21x24', 'UK 23x35', 'UK 20x26', 'UK 33x23', 'UK 29x23', 'NL 27x21', 'US 22x20', 'FR 26x34', 'US 21x34', 'FR 24x23', 'UK 21x35', 'NL 33x23', 'US 23x23', 'NL 30x25', 'US 25x29', 'US 25x28', 'NL 34x33', 'FR 34x26', 'NL 24x33', 'UK 21x24', 'NL 29x20', 'NL 28x21', 'US 20x25', 'NL 25x27', 'NL 34x27', 'UK 26x27', 'FR 20x25', 'FR 31x24', 'US 23x23', 'FR 34x24', 'US 23x27', 'US 26x21', 'UK 30x27', 'UK 33x35', 'NL 29x26', 'UK 21x35', 'NL 25x24', 'UK 24x20', 'UK 25x28', 'UK 23x31', 'FR 20x31', 'UK 25x27', 'UK 29x24', 'NL 26x32', 'FR 28x34', 'US 30x25', 'NL 21x30', 'UK 28x23', 'UK 21x27', 'NL 31x31', 'UK 26x22', 'FR 20x25', 'UK 22x24', 'NL 28x23', 'UK 31x32', 'UK 30x21', 'FR 28x24', 'US 26x26', 'US 20x29', 'UK 31x28', 'US 32x28', 'UK 27x35', 'US 29x33', 'NL 22x32', 'UK 24x33', 'US 32x33', 'US 26x30', 'US 35x32', 'NL 35x35', 'NL 24x34', 'NL 33x35', 'FR 24x23', 'US 26x32', 'NL 27x21', 'UK 27x31', 'FR 25x27', 'UK 27x29', 'NL 27x35', 'NL 30x33', 'UK 24x30', 'UK 27x20', 'FR 29x23', 'FR 25x34', 'US 30x34', 'US 24x24', 'NL 27x23', 'UK 35x31', 'US 35x34']