Add elisp/roman-numerals
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# Roman Numerals
|
||||
|
||||
Write a function to convert from normal numbers to Roman Numerals.
|
||||
|
||||
The Romans were a clever bunch. They conquered most of Europe and ruled
|
||||
it for hundreds of years. They invented concrete and straight roads and
|
||||
even bikinis. One thing they never discovered though was the number
|
||||
zero. This made writing and dating extensive histories of their exploits
|
||||
slightly more challenging, but the system of numbers they came up with
|
||||
is still in use today. For example the BBC uses Roman numerals to date
|
||||
their programmes.
|
||||
|
||||
The Romans wrote numbers using letters - I, V, X, L, C, D, M. (notice
|
||||
these letters have lots of straight lines and are hence easy to hack
|
||||
into stone tablets).
|
||||
|
||||
```
|
||||
1 => I
|
||||
10 => X
|
||||
7 => VII
|
||||
```
|
||||
|
||||
There is no need to be able to convert numbers larger than about 3000.
|
||||
(The Romans themselves didn't tend to go any higher)
|
||||
|
||||
Wikipedia says: Modern Roman numerals ... are written by expressing each
|
||||
digit separately starting with the left most digit and skipping any
|
||||
digit with a value of zero.
|
||||
|
||||
To see this in practice, consider the example of 1990.
|
||||
|
||||
In Roman numerals 1990 is MCMXC:
|
||||
|
||||
1000=M
|
||||
900=CM
|
||||
90=XC
|
||||
|
||||
2008 is written as MMVIII:
|
||||
|
||||
2000=MM
|
||||
8=VIII
|
||||
|
||||
See also: http://www.novaroma.org/via_romana/numbers.html
|
||||
## Source
|
||||
|
||||
The Roman Numeral Kata [http://codingdojo.org/cgi-bin/index.pl?KataRomanNumerals](http://codingdojo.org/cgi-bin/index.pl?KataRomanNumerals)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
||||
@@ -0,0 +1,30 @@
|
||||
;;; roman-numerals-test.el --- Tests for roman-numerals (exercism)
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;; Code:
|
||||
|
||||
(load-file "roman-numerals.el")
|
||||
|
||||
(ert-deftest roman-numerals-test ()
|
||||
(should (equal (to-roman 1) "I"))
|
||||
(should (equal (to-roman 2) "II"))
|
||||
(should (equal (to-roman 3) "III"))
|
||||
(should (equal (to-roman 4) "IV"))
|
||||
(should (equal (to-roman 5) "V"))
|
||||
(should (equal (to-roman 6) "VI"))
|
||||
(should (equal (to-roman 9) "IX"))
|
||||
(should (equal (to-roman 27) "XXVII"))
|
||||
(should (equal (to-roman 48) "XLVIII"))
|
||||
(should (equal (to-roman 59) "LIX"))
|
||||
(should (equal (to-roman 93) "XCIII"))
|
||||
(should (equal (to-roman 141) "CXLI"))
|
||||
(should (equal (to-roman 163) "CLXIII"))
|
||||
(should (equal (to-roman 402) "CDII"))
|
||||
(should (equal (to-roman 575) "DLXXV"))
|
||||
(should (equal (to-roman 911) "CMXI"))
|
||||
(should (equal (to-roman 1024) "MXXIV"))
|
||||
(should (equal (to-roman 3000) "MMM")))
|
||||
|
||||
(provide 'roman-numerals)
|
||||
;;; roman-numerals-test.el ends here
|
||||
@@ -0,0 +1,46 @@
|
||||
;;; roman-numerals.el --- roman-numerals Exercise (exercism)
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;; Code:
|
||||
|
||||
(provide 'roman-numerals)
|
||||
|
||||
(defun greatest-roman-amount (n)
|
||||
(cond ((>= n 1000) 1000)
|
||||
((>= n 900) 900)
|
||||
((>= n 500) 500)
|
||||
((>= n 400) 400)
|
||||
((>= n 100) 100)
|
||||
((>= n 90) 90)
|
||||
((>= n 50) 50)
|
||||
((>= n 40) 40)
|
||||
((>= n 10) 10)
|
||||
((>= n 9) 9)
|
||||
((>= n 5) 5)
|
||||
((>= n 4) 4)
|
||||
((>= n 1) 1)))
|
||||
|
||||
(defun numeral-for-amount (n)
|
||||
(cond ((= n 1000) "M")
|
||||
((= n 900) "CM")
|
||||
((= n 500) "D")
|
||||
((= n 400) "CD")
|
||||
((= n 100) "C")
|
||||
((= n 90) "XC")
|
||||
((= n 50) "L")
|
||||
((= n 40) "XL")
|
||||
((= n 10) "X")
|
||||
((= n 9) "IX")
|
||||
((= n 5) "V")
|
||||
((= n 4) "IV")
|
||||
((= n 1) "I")))
|
||||
|
||||
(defun to-roman (n)
|
||||
"Convert whole number N to roman numeral.
|
||||
Does not handle numbers greater than 3000."
|
||||
(cl-loop until (<= n 0)
|
||||
concat (numeral-for-amount (greatest-roman-amount n))
|
||||
do (setq n (- n (greatest-roman-amount n)))))
|
||||
|
||||
;;; roman-numerals.el ends here
|
||||
Reference in New Issue
Block a user