You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit f94e8cd
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: exercises/practice/roman-numerals/.approaches/introduction.md
+28-29Lines changed: 28 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,29 +9,28 @@ In the version used for this exercise, the longest string needed to represent a
9
9
Minor variants of the system have been used which represent 4 as IIII rather than IV, allowing for longer strings, but those are not relevant here.
10
10
11
11
The system is inherently decimal: the number of human fingers has not changed since ancient Rome, nor the habit of using them for counting.
12
-
However, there is no zero value available, so Roman numerals represent powers of 10 with different letters (I, X, C, M), not by position (1, 10, 100, 1000).
12
+
However, there is no zero value available, so Roman numerals represent powers of 10 with different letters (I, X, C, and M), not by position (1, 10, 100, 1000, etc).
13
13
14
14
The approaches to this exercise break down into two groups, with many variants in each:
15
+
15
16
1. Split the input number into digits, and translate each separately.
16
17
2. Iterate through the Roman numbers, from large to small, and convert the largest valid number at each step.
17
18
18
19
## Digit-by-digit approaches
19
20
20
-
The concept behind this class of approaches:
21
-
1. Split the input number into decimal digits.
22
-
2. For each digit, get the Roman equivalent and append to a list.
23
-
3. Join the list into a string and return it.
21
+
The process behind this class of approaches:
22
+
23
+
1. Split the input number into decimal digits.
24
+
2. For each digit, get the Roman equivalent and append to a list.
25
+
3. Join the list into a string and return it.
26
+
24
27
Depending on the implementation, there may need to be a list-reverse step.
This approach is certainly concise and ingenious, though it takes functional programming to a level that some Python programmers might consider a little cryptic.
@@ -24,7 +24,7 @@ The underlying reason is that lambdas are intended to be anonymous functions emb
24
24
Internally, they are all given the same name `<lambda>`, which can greatly complicate debugging.
25
25
Their use is a particular bugbear of the Python track maintainer.
26
26
27
-
We can refactor the code to satisfy the linter by using named `def` statements, and lowercase argument names.
27
+
We can refactor the code to satisfy the linter by using named `def` statements and lowercase argument names.
28
28
Type hints are also added for documentation:
29
29
30
30
```python
@@ -33,21 +33,21 @@ from itertools import starmap
33
33
34
34
defroman(number: int) -> str:
35
35
defoptions(i: str, v: str, x: str):
36
-
return ["", i, i *2, i *3, i + v, v, v + i, v + i *2, v + i *3, i + x]
36
+
return ['', i, i *2, i *3, i + v, v, v + i, v + i *2, v + i *3, i + x]
The central concept is that Roman letters are defined for 1, 5 and 10, times various powers of 10.
48
48
49
-
`orders` is relatively straightforward: a list of tuples, with each tuple containing the powers of 10 and (as far as possible) the letters for that number times (1, 5, 10).
50
-
Roman numerals for 5,000 and 10,000 are not defined, so are replaced here by spaces.
49
+
`orders` is relatively straightforward: a list of tuples, with each tuple containing the powers of 10 and (as far as possible) the letters for that number times (1, 5, 10).
50
+
Roman numerals for 5,000 and 10,000 are not defined, so spaces are used here instead.
51
51
52
52
The `options()` function just takes the three letters from one of these tuples and returns a list of numerals that can be constructed from them.
53
53
For example, the 10 to 90 range:
@@ -60,15 +60,15 @@ options('X', 'L', 'C')
60
60
There is no zero, so that is replaced by an empty string.
61
61
62
62
The `compute()` function takes a tuple from `orders` plus the top-level parameter `number`, and converts the appropriate decimal digit to its Roman equivalent, returning an `iterator`.
63
-
For example the first digit of 723:
63
+
For example, the first digit of 723:
64
64
65
65
```python
66
66
number =723
67
-
[x for x in compute(100, "CDM")]
67
+
[x for x in compute(100, 'CDM')]
68
68
# => ['D', 'C', 'C']
69
69
```
70
70
71
-
The `starmap()` function ties `orders`, `options()` and `compute` together, splitting up strings and tuples as necessary to give each function the parameters it needs.
71
+
The `starmap()` function ties `orders`, `options()`, and `compute()` together, splitting up strings and tuples as necessary to give each function the parameters it needs.
72
72
Again, an iterator is returned:
73
73
74
74
```python
@@ -79,7 +79,7 @@ number = 723
79
79
80
80
Finally, `''.join()` converts this iterator to a single string that can be returned as the desired answer.
81
81
82
-
Once we get past the deliberate obfuscation, it is quite an elegant approach.
82
+
Once we get past the deliberate obfuscation, it is quite an elegant approach.
0 commit comments