Сьогодні більшість людей у світі користується арабськими цифрами (0–9). Але якби ми перенеслися на дві тисячі років назад, то побачили б, що більшість європейців користувалася натомість римськими цифрами.
Щоб записати римську цифру, ми використовуємо такі латинські літери, кожна з яких має своє значення:
| M | D | C | L | X | V | I |
|---|---|---|---|---|---|---|
| 1000 | 500 | 100 | 50 | 10 | 5 | 1 |
Римська цифра - це послідовність таких літер, а її значення - сума значень цих літер.
Наприклад, XVIII має значення 18 (10 + 5 + 1 + 1 + 1 = 18).
Але є одне правило, яке все ускладнює: ту саму літеру не можна використовувати більше ніж тричі підряд.
Це означає, що ми не можемо записати такі числа, як 4, здавалося б природним IIII.
Замість цього для таких чисел ми використовуємо метод віднімання між двома літерами.
Тож ми уявляємо 4 не як 1 + 1 + 1 + 1, а натомість як 5 - 1.
І, що трохи збиває з пантелику наше сучасне мислення, спершу ми пишемо менше число.
Це стосується лише таких випадків: 4 (IV), 9 (IX), 40 (XL), 90 (XC), 400 (CD) і 900 (CM).
У римських цифрах порядок має значення! Літери (і наведені вище особливі сполуки) потрібно впорядковувати за спаданням значення зліва направо.
Ось кілька прикладів:
105 => CV
---- => --
100 => C
+ 5 => V
106 => CVI
---- => --
100 => C
+ 5 => V
+ 1 => I
104 => CIV
---- => ---
100 => C
+ 4 => IV
А ось складніший приклад наостанок:
1996 => MCMXCVI
----- => -------
1000 => M
+ 900 => CM
+ 90 => XC
+ 5 => V
+ 1 => I
Завдання - перетворити число з арабських цифр на римські.
У цій вправі йдеться лише про традиційні римські цифри, у яких найбільше число - MMMCMXCIX (або 3 999).
Існує багато різних способів перетворювати арабські цифри на римські й навпаки. Радимо спершу застосувати найпростіший підхід, щоб ознайомитися з поняттям римських цифр, а вже потім шукати ефективніші методи.
Не забудьмо подивитися наше відео Deep Dive наприкінці, щоб дослідити різні підходи, які можна застосувати!
У цій вправі нам потрібно підтримати два різні способи виклику слова stringify:
roman (наприклад, stringify.roman 3999)roman (наприклад, stringify 3999)Щоб дізнатися більше, перегляньте документацію атрибутів, а також документацію attr.
Окрім attr, корисна також функція attrs: вона повертає всі атрибути виклику функції як словник.
Зауважмо: ці дві функції деструктивні!
Реалізація Arturo використовує «таблицю атрибутів».
attrs явно спорожнює таблицю після отримання атрибутів.attr видаляє («виштовхує») атрибут із таблиці.Приклад:
showAttributes: function [x][
print attr 'question
print attrs
print attrs
]
showAttributes .question:"6 * 9" .answer:42 'arg
виводить
6 * 9
[answer:42]
[]
На кожному кроці ми бачимо, як словник атрибутів зменшується.
Висновок: памʼятаймо, що атрибути можна отримати лише один раз. Якщо потрібно звернутися до атрибутів ще раз, збережімо їх на початку наших функцій.
Зареєструйтеся на Exercism, щоб вивчати й опановувати Arturo, а також 79 вправ та справжнє наставництво від людей, і все це безкоштовно.
Розгляньте різноманітні розвʼязки цієї непростої вправи: від рекурсії до пошуку за таблицями, одне рішення, що використовує числа зі змішаною основою, та трохи простенького шахрайства з боку Common Lisp.