# Puzzle solutions
## Convert to Roman Numerals
### Andrew
:::spoiler
```python
code
```
:::
### Jan
:::spoiler
```python=
char_map = [
(1, 'I'),
(4, 'IV'),
(5, 'V'),
(9, 'IX'),
(10, 'X'),
(40, 'XL'),
(50, 'L'),
(90, 'XC'),
(100, 'C'),
(400, 'CD'),
(500, 'D'),
(900, 'CM'),
(1000, 'M'),
]
def arabic_to_roman(arabic):
for (a, r) in reversed(char_map):
if arabic == a:
return r
if arabic > a:
return f"{r}{arabic_to_roman(arabic - a)}"
@pytest.mark.parametrize('arabic,roman', [
(1, 'I'),
(2, 'II'),
(3, 'III'),
(4, 'IV'),
(5, 'V'),
(6, 'VI'),
(7, 'VII'),
(8, 'VIII'),
(9, 'IX'),
(10, 'X'),
(11, 'XI'),
(20, 'XX'),
(23, 'XXIII'),
(24, 'XXIV'),
(25, 'XXV'),
(27, 'XXVII'),
(29, 'XXIX'),
(30, 'XXX'),
(39, 'XXXIX'),
(40, 'XL'),
(50, 'L'),
(60, 'LX'),
(70, 'LXX'),
(73, 'LXXIII'),
(80, 'LXXX'),
(90, 'XC'),
(100, 'C'),
(110, 'CX'),
(190, 'CXC'),
(200, 'CC'),
(300, 'CCC'),
(400, 'CD'),
(492, 'CDXCII'),
(500, 'D'),
(600, 'DC'),
(700, 'DCC'),
(800, 'DCCC'),
(900, 'CM'),
(1000, 'M'),
(1048, 'MXLVIII'),
(1100, 'MC'),
(2000, 'MM'),
(2001, 'MMI'),
(3000, 'MMM'),
(3549, 'MMMDXLIX'),
(3999, 'MMMCMXCIX'),
])
def test_arabic_to_roman(arabic, roman):
assert arabic_to_roman(arabic) == roman
```
:::
### George
:::spoiler
```python=
# numerals.py
import math
fours_map = {1:"IV", 2:"XL", 3:"CD", 4:"__\nIV"}
fives_map = {1:"V", 2:"L", 3:"D"}
nines_map = {1:"IX", 2:"XC", 3:"CM"}
main_map = {1:"I", 2:"X", 3:"C", 4:"M"}
def conversion(arabic_num):
if isinstance(arabic_num, int) and 1 <= arabic_num <= 3999:
list_num = [int(i) for i in str(arabic_num)]
roman_str = ""
for index, value in enumerate(list_num):
if value == 4:
roman_str += fours_map[len(list_num) - index]
elif value == 9:
roman_str += nines_map[len(list_num) - index]
else:
if value >= 5:
roman_str += fives_map[len(list_num) - index]
value -= 5
for num in range(value):
roman_str += main_map[len(list_num) - index]
return roman_str
else:
return "invalid input. please input an integer between 1 and 3999"
###################################################################################
# test.py
import pytest
import numerals
def test_basic_conversion():
assert numerals.conversion(1) == "I"
assert numerals.conversion(2) == "II"
assert numerals.conversion(3) == "III"
def test_four_conversion():
assert numerals.conversion(4) == "IV"
def test_fives_conversion():
assert numerals.conversion(5) == "V"
assert numerals.conversion(6) == "VI"
assert numerals.conversion(7) == "VII"
assert numerals.conversion(8) == "VIII"
def test_nine_conversion():
assert numerals.conversion(9) == "IX"
def test_10s_conversion():
assert numerals.conversion(10) == "X"
assert numerals.conversion(11) == "XI"
assert numerals.conversion(12) == "XII"
assert numerals.conversion(13) == "XIII"
def test_complex_conversion():
assert numerals.conversion(14) == "XIV"
assert numerals.conversion(15) == "XV"
assert numerals.conversion(17) == "XVII"
assert numerals.conversion(19) == "XIX"
def test_20s_30s_conversion():
assert numerals.conversion(20) == "XX"
assert numerals.conversion(23) == "XXIII"
assert numerals.conversion(24) == "XXIV"
assert numerals.conversion(27) == "XXVII"
assert numerals.conversion(29) == "XXIX"
assert numerals.conversion(30) == "XXX"
assert numerals.conversion(39) == "XXXIX"
def test_40_conversion():
assert numerals.conversion(40) == "XL"
def test_50_conversion():
assert numerals.conversion(50) == "L"
def test_90_conversion():
assert numerals.conversion(90) == "XC"
def test_100_conversion():
assert numerals.conversion(100) == "C"
def test_400_conversion():
assert numerals.conversion(400) == "CD"
def test_500_conversion():
assert numerals.conversion(500) == "D"
def test_900_conversion():
assert numerals.conversion(900) == "CM"
def test_1000_conversion():
assert numerals.conversion(1000) == "M"
def test_random_numbers():
assert numerals.conversion(3549) == "MMMDXLIX"
assert numerals.conversion(3999) == "MMMCMXCIX"
assert numerals.conversion(1048) == "MXLVIII"
assert numerals.conversion(2001) == "MMI"
assert numerals.conversion(492) == "CDXCII"
def test_random_numbers():
assert numerals.conversion(9999) == "invalid input. please input an integer between 1 and 3999"
assert numerals.conversion("3549") == "invalid input. please input an integer between 1 and 3999"
assert numerals.conversion("not a number") == "invalid input. please input an integer between 1 and 3999"
```
:::
## 99 bottles
### Jan
#### basic `range` solution
:::spoiler
```python=
def bottles_func(start_amount):
lyrics = ""
for n in range(start_amount, 1, -1):
lyrics += f"{n} bottles of beer on the wall, {n} bottles of beer.\n"
if n > 2:
lyrics += f"Take one down and pass it around, {n-1} bottles of beer on the wall.\n\n"
else:
lyrics += "Take one down and pass it around, 1 bottle of beer on the wall.\n\n"
lyrics += "Take one down and pass it around, no more bottles of beer on the wall.\n\n"
lyrics += "No more bottles of beer on the wall, no more bottles of beer.\n"
lyrics += "Go to the store and buy some more, 99 bottles of beer on the wall."
return lyrics
def test_bottles():
result = bottles_func(99)
expected = ""
for n in range(99, 1, -1):
expected += f"{n} bottles of beer on the wall, {n} bottles of beer.\n"
if n > 1:
expected += f"Take one dow and pass it around, {n-1} bottles of beer on the wall.\n\n"
expected += "Take one down and pass it around, no more bottles of beer on the wall.\n\n"
expected += "No more bottles of beer on the wall, no more bottles of beer.\n"
expected += "Go to the store and buy some more, 99 bottles of beer on the wall."
assert result == expected
```
:::
#### generator solution
:::spoiler
```python=
def bottles_generator():
def pluralize(num, word):
if num > 1:
return f"{word}s"
return word
start_amount = 99
for n in range(start_amount, 1, -1):
yield f"{n} bottles of beer on the wall, {n} bottles of beer.\nTake one down, pass it around, {n-1} {pluralize(n-1, 'bottle')} of beer on the wall."
yield "1 bottle of beer on the wall, 1 bottle of beer.\nTake one down, pass it around, no more bottles of beer on the wall."
yield f"No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, {start_amount} bottles of beer on the wall."
def test_bottles_generator():
n = 99
for verse in bottles_generator():
if n > 2:
assert verse == f"{n} bottles of beer on the wall, {n} bottles of beer.\nTake one down, pass it around, {n-1} bottles of beer on the wall."
elif n == 2:
assert verse == "2 bottles of beer on the wall, 2 bottles of beer.\nTake one down, pass it around, 1 bottle of beer on the wall."
elif n == 1:
assert verse == "1 bottle of beer on the wall, 1 bottle of beer.\nTake one down, pass it around, no more bottles of beer on the wall."
else:
assert verse == "No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall."
n -= 1
assert n == -1
```
:::
### Andrew
:::spoiler
```
import pytest
import os
def printy():
beers = 99
while beers > 1:
print(str(beers) + " bottles of beer on the wall, "+str(beers)+" bottles of beer.")
beers = beers - 1
print("Take one down and pass it around, " + str(beers) + " bottles of beer on the wall.")
print() # need newline
if beers == 1:
print("1 bottle of beer on the wall, 1 bottle of beer.\nTake one down and pass it around, no more bottles of beer on the wall.")
print()
print("No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.")
def test_99(capsys):
printy()
captured = capsys.readouterr()
assert captured.out == "99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.
98 bottles of beer on the wall, 98 bottles of beer.
Take one down and pass it around, 97 bottles of beer on the wall.
97 bottles of beer on the wall, 97 bottles of beer.
Take one down and pass it around, 96 bottles of beer on the wall.
96 bottles of beer on the wall, 96 bottles of beer.
Take one down and pass it around, 95 bottles of beer on the wall.
95 bottles of beer on the wall, 95 bottles of beer.
Take one down and pass it around, 94 bottles of beer on the wall.
94 bottles of beer on the wall, 94 bottles of beer.
Take one down and pass it around, 93 bottles of beer on the wall.
93 bottles of beer on the wall, 93 bottles of beer.
Take one down and pass it around, 92 bottles of beer on the wall.
92 bottles of beer on the wall, 92 bottles of beer.
Take one down and pass it around, 91 bottles of beer on the wall.
91 bottles of beer on the wall, 91 bottles of beer.
Take one down and pass it around, 90 bottles of beer on the wall.
90 bottles of beer on the wall, 90 bottles of beer.
Take one down and pass it around, 89 bottles of beer on the wall.
89 bottles of beer on the wall, 89 bottles of beer.
Take one down and pass it around, 88 bottles of beer on the wall.
88 bottles of beer on the wall, 88 bottles of beer.
Take one down and pass it around, 87 bottles of beer on the wall.
87 bottles of beer on the wall, 87 bottles of beer.
Take one down and pass it around, 86 bottles of beer on the wall.
86 bottles of beer on the wall, 86 bottles of beer.
Take one down and pass it around, 85 bottles of beer on the wall.
85 bottles of beer on the wall, 85 bottles of beer.
Take one down and pass it around, 84 bottles of beer on the wall.
84 bottles of beer on the wall, 84 bottles of beer.
Take one down and pass it around, 83 bottles of beer on the wall.
83 bottles of beer on the wall, 83 bottles of beer.
Take one down and pass it around, 82 bottles of beer on the wall.
82 bottles of beer on the wall, 82 bottles of beer.
Take one down and pass it around, 81 bottles of beer on the wall.
81 bottles of beer on the wall, 81 bottles of beer.
Take one down and pass it around, 80 bottles of beer on the wall.
80 bottles of beer on the wall, 80 bottles of beer.
Take one down and pass it around, 79 bottles of beer on the wall.
79 bottles of beer on the wall, 79 bottles of beer.
Take one down and pass it around, 78 bottles of beer on the wall.
78 bottles of beer on the wall, 78 bottles of beer.
Take one down and pass it around, 77 bottles of beer on the wall.
77 bottles of beer on the wall, 77 bottles of beer.
Take one down and pass it around, 76 bottles of beer on the wall.
76 bottles of beer on the wall, 76 bottles of beer.
Take one down and pass it around, 75 bottles of beer on the wall.
75 bottles of beer on the wall, 75 bottles of beer.
Take one down and pass it around, 74 bottles of beer on the wall.
74 bottles of beer on the wall, 74 bottles of beer.
Take one down and pass it around, 73 bottles of beer on the wall.
73 bottles of beer on the wall, 73 bottles of beer.
Take one down and pass it around, 72 bottles of beer on the wall.
72 bottles of beer on the wall, 72 bottles of beer.
Take one down and pass it around, 71 bottles of beer on the wall.
71 bottles of beer on the wall, 71 bottles of beer.
Take one down and pass it around, 70 bottles of beer on the wall.
70 bottles of beer on the wall, 70 bottles of beer.
Take one down and pass it around, 69 bottles of beer on the wall.
69 bottles of beer on the wall, 69 bottles of beer.
Take one down and pass it around, 68 bottles of beer on the wall.
68 bottles of beer on the wall, 68 bottles of beer.
Take one down and pass it around, 67 bottles of beer on the wall.
67 bottles of beer on the wall, 67 bottles of beer.
Take one down and pass it around, 66 bottles of beer on the wall.
66 bottles of beer on the wall, 66 bottles of beer.
Take one down and pass it around, 65 bottles of beer on the wall.
65 bottles of beer on the wall, 65 bottles of beer.
Take one down and pass it around, 64 bottles of beer on the wall.
64 bottles of beer on the wall, 64 bottles of beer.
Take one down and pass it around, 63 bottles of beer on the wall.
63 bottles of beer on the wall, 63 bottles of beer.
Take one down and pass it around, 62 bottles of beer on the wall.
62 bottles of beer on the wall, 62 bottles of beer.
Take one down and pass it around, 61 bottles of beer on the wall.
61 bottles of beer on the wall, 61 bottles of beer.
Take one down and pass it around, 60 bottles of beer on the wall.
60 bottles of beer on the wall, 60 bottles of beer.
Take one down and pass it around, 59 bottles of beer on the wall.
59 bottles of beer on the wall, 59 bottles of beer.
Take one down and pass it around, 58 bottles of beer on the wall.
58 bottles of beer on the wall, 58 bottles of beer.
Take one down and pass it around, 57 bottles of beer on the wall.
57 bottles of beer on the wall, 57 bottles of beer.
Take one down and pass it around, 56 bottles of beer on the wall.
56 bottles of beer on the wall, 56 bottles of beer.
Take one down and pass it around, 55 bottles of beer on the wall.
55 bottles of beer on the wall, 55 bottles of beer.
Take one down and pass it around, 54 bottles of beer on the wall.
54 bottles of beer on the wall, 54 bottles of beer.
Take one down and pass it around, 53 bottles of beer on the wall.
53 bottles of beer on the wall, 53 bottles of beer.
Take one down and pass it around, 52 bottles of beer on the wall.
52 bottles of beer on the wall, 52 bottles of beer.
Take one down and pass it around, 51 bottles of beer on the wall.
51 bottles of beer on the wall, 51 bottles of beer.
Take one down and pass it around, 50 bottles of beer on the wall.
50 bottles of beer on the wall, 50 bottles of beer.
Take one down and pass it around, 49 bottles of beer on the wall.
49 bottles of beer on the wall, 49 bottles of beer.
Take one down and pass it around, 48 bottles of beer on the wall.
48 bottles of beer on the wall, 48 bottles of beer.
Take one down and pass it around, 47 bottles of beer on the wall.
47 bottles of beer on the wall, 47 bottles of beer.
Take one down and pass it around, 46 bottles of beer on the wall.
46 bottles of beer on the wall, 46 bottles of beer.
Take one down and pass it around, 45 bottles of beer on the wall.
45 bottles of beer on the wall, 45 bottles of beer.
Take one down and pass it around, 44 bottles of beer on the wall.
44 bottles of beer on the wall, 44 bottles of beer.
Take one down and pass it around, 43 bottles of beer on the wall.
43 bottles of beer on the wall, 43 bottles of beer.
Take one down and pass it around, 42 bottles of beer on the wall.
42 bottles of beer on the wall, 42 bottles of beer.
Take one down and pass it around, 41 bottles of beer on the wall.
41 bottles of beer on the wall, 41 bottles of beer.
Take one down and pass it around, 40 bottles of beer on the wall.
40 bottles of beer on the wall, 40 bottles of beer.
Take one down and pass it around, 39 bottles of beer on the wall.
39 bottles of beer on the wall, 39 bottles of beer.
Take one down and pass it around, 38 bottles of beer on the wall.
38 bottles of beer on the wall, 38 bottles of beer.
Take one down and pass it around, 37 bottles of beer on the wall.
37 bottles of beer on the wall, 37 bottles of beer.
Take one down and pass it around, 36 bottles of beer on the wall.
36 bottles of beer on the wall, 36 bottles of beer.
Take one down and pass it around, 35 bottles of beer on the wall.
35 bottles of beer on the wall, 35 bottles of beer.
Take one down and pass it around, 34 bottles of beer on the wall.
34 bottles of beer on the wall, 34 bottles of beer.
Take one down and pass it around, 33 bottles of beer on the wall.
33 bottles of beer on the wall, 33 bottles of beer.
Take one down and pass it around, 32 bottles of beer on the wall.
32 bottles of beer on the wall, 32 bottles of beer.
Take one down and pass it around, 31 bottles of beer on the wall.
31 bottles of beer on the wall, 31 bottles of beer.
Take one down and pass it around, 30 bottles of beer on the wall.
30 bottles of beer on the wall, 30 bottles of beer.
Take one down and pass it around, 29 bottles of beer on the wall.
29 bottles of beer on the wall, 29 bottles of beer.
Take one down and pass it around, 28 bottles of beer on the wall.
28 bottles of beer on the wall, 28 bottles of beer.
Take one down and pass it around, 27 bottles of beer on the wall.
27 bottles of beer on the wall, 27 bottles of beer.
Take one down and pass it around, 26 bottles of beer on the wall.
26 bottles of beer on the wall, 26 bottles of beer.
Take one down and pass it around, 25 bottles of beer on the wall.
25 bottles of beer on the wall, 25 bottles of beer.
Take one down and pass it around, 24 bottles of beer on the wall.
24 bottles of beer on the wall, 24 bottles of beer.
Take one down and pass it around, 23 bottles of beer on the wall.
23 bottles of beer on the wall, 23 bottles of beer.
Take one down and pass it around, 22 bottles of beer on the wall.
22 bottles of beer on the wall, 22 bottles of beer.
Take one down and pass it around, 21 bottles of beer on the wall.
21 bottles of beer on the wall, 21 bottles of beer.
Take one down and pass it around, 20 bottles of beer on the wall.
20 bottles of beer on the wall, 20 bottles of beer.
Take one down and pass it around, 19 bottles of beer on the wall.
19 bottles of beer on the wall, 19 bottles of beer.
Take one down and pass it around, 18 bottles of beer on the wall.
18 bottles of beer on the wall, 18 bottles of beer.
Take one down and pass it around, 17 bottles of beer on the wall.
17 bottles of beer on the wall, 17 bottles of beer.
Take one down and pass it around, 16 bottles of beer on the wall.
16 bottles of beer on the wall, 16 bottles of beer.
Take one down and pass it around, 15 bottles of beer on the wall.
15 bottles of beer on the wall, 15 bottles of beer.
Take one down and pass it around, 14 bottles of beer on the wall.
14 bottles of beer on the wall, 14 bottles of beer.
Take one down and pass it around, 13 bottles of beer on the wall.
13 bottles of beer on the wall, 13 bottles of beer.
Take one down and pass it around, 12 bottles of beer on the wall.
12 bottles of beer on the wall, 12 bottles of beer.
Take one down and pass it around, 11 bottles of beer on the wall.
11 bottles of beer on the wall, 11 bottles of beer.
Take one down and pass it around, 10 bottles of beer on the wall.
10 bottles of beer on the wall, 10 bottles of beer.
Take one down and pass it around, 9 bottles of beer on the wall.
9 bottles of beer on the wall, 9 bottles of beer.
Take one down and pass it around, 8 bottles of beer on the wall.
8 bottles of beer on the wall, 8 bottles of beer.
Take one down and pass it around, 7 bottles of beer on the wall.
7 bottles of beer on the wall, 7 bottles of beer.
Take one down and pass it around, 6 bottles of beer on the wall.
6 bottles of beer on the wall, 6 bottles of beer.
Take one down and pass it around, 5 bottles of beer on the wall.
5 bottles of beer on the wall, 5 bottles of beer.
Take one down and pass it around, 4 bottles of beer on the wall.
4 bottles of beer on the wall, 4 bottles of beer.
Take one down and pass it around, 3 bottles of beer on the wall.
3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.
2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottles of beer on the wall.
1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall."
```
:::
### Eric
:::spoiler
```python=
strings = ['{} bottles of beer on the wall, {} bottles of beer.\n', 'Take one down and pass it around, {} more bottles of beer on the wall.\n', 'No more bottles of beer on the wall, no more bottles of beer.\n', 'Go to the store and buy some more, 99 bottles of beer on the wall.']
@pytest.fixture
def beer():
beer = ""
for i in range(99, 0, -1):
beer += f"{strings[0].format(i, i)}{strings[1].format(i - 1)}" if i > 1 else f"{strings[0].format(i, i)}{strings[1].format('no')}{strings[2]}{strings[3]}"
return beer.split('\n')
def test_beer(beer):
counter = 99
for i in range(len(beer)):
assert beer[i] == f"{strings[0].format(counter, counter).strip()}" or beer[i] == f"{strings[1].format(counter - 1).strip()}" or beer[i] == f"{strings[0].format(counter, counter).strip()}" or beer[i] == f"{strings[1].format('no').strip()}" or beer[i] == f"{strings[2].strip()}" or beer[i] == f"{strings[3].strip()}"
if strings[1][:9] in beer[i] and counter > 1: counter -= 1
```
:::