All original content is created in Ukrainian. Not all content has been translated yet. Some posts may only be available in Ukrainian.Learn more

Задача: Перетворення римського числа на десяткове (Ruby)

Post cover: Задача: Перетворення римського числа на десяткове (Ruby)
This content has not been translated yet.We're showing the original Ukrainian content below.
Розглянемо простий варіант вирішення задачі по перетворенню римського числа на десяткове (Ruby).

Умова

Створіть функцію solution, яка приймає рядок — римське число — і повертає його значення як десяткове ціле число.
Валідацію правильності римського запису робити не потрібно.
Приклади:
  • "MCMXC" → 1990
  • "MMVIII" → 2008
  • "MDCLXVI" → 1666

Як працює конвертація римських чисел у десяткові?

Римські числа — це система числення, що базується на символах, кожен з яких відповідає певному значенню: I — 1, V — 5, X — 10, L — 50, C — 100, D — 500, M — 1000. Для запису числа символи комбінуються за певними правилами. Якщо символ меншого значення стоїть перед більшим (наприклад, IV), це означає віднімання (5 - 1 = 4). Якщо ж навпаки — додаються (VI = 5 + 1 = 6). Завдяки такій логіці можна компактно записувати як прості числа, так і складні, як-от MCMXC для 1990.
При перетворенні римських чисел у десяткові комп’ютерний алгоритм проходить символи рядка справа наліво. Це дає змогу легко визначити, чи потрібно додати значення символа, чи відняти його. Наприклад, у XIV обробка починається з V = 5, потім I = 1 (менше за V, тому віднімаємо: 5 - 1 = 4), потім X = 10 (більше за I, тому додаємо: 10 + 4 = 14). Такий підхід дозволяє ефективно реалізувати перетворення навіть у кілька рядків коду.

Тест (rspec) для перевірки методу

RSpec.describe '#solution' do
  it 'перетворює прості римські числа' do
    expect(solution('I')).to eq(1)
    expect(solution('III')).to eq(3)
    expect(solution('VIII')).to eq(8)
  end

  it 'перетворює складені римські числа' do
    expect(solution('IV')).to eq(4)
    expect(solution('IX')).to eq(9)
    expect(solution('XL')).to eq(40)
    expect(solution('XC')).to eq(90)
  end

  it 'перетворює великі римські числа' do
    expect(solution('MCMXC')).to eq(1990)
    expect(solution('MMVIII')).to eq(2008)
    expect(solution('MDCLXVI')).to eq(1666)
    expect(solution('MMMCMXCIX')).to eq(3999)
  end
end

Метод solution

Один з варіантів вирішення (за допомогою Ruby одні й ті самі штуки можна роботи багатьма способами).
def solution(roman)
  values = {
    'M' => 1000,
    'D' => 500,
    'C' => 100,
    'L' => 50,
    'X' => 10,
    'V' => 5,
    'I' => 1
  }

  total = 0
  prev = 0

  roman.chars.reverse.each do |char|
    current = values[char]
    if current < prev
      total -= current
    else
      total += current
      prev = current
    end
  end

  total
end

Принцип роботи алгоритму

Ми рухаємось з кінця рядка, додаючи значення символів. Якщо поточне число менше за попереднє — віднімаємо його, інакше — додаємо. Це дозволяє коректно обробляти випадки на кшталт IV чи CM.

This post doesn't have any additions from the author yet.

[Codecov] What is the difference between patch and project coverage?
09 Apr 16:03

[Codecov] What is the difference between patch and project coverage?

meme code
meme code@memecode
How do Scratch courses help children develop soft skills?
11 Apr 18:24

How do Scratch courses help children develop soft skills?

meme code
meme code@memecode
24 Apr 20:17

Фіксимо minikube "You are trying to run the amd64 binary on an M1 system."

meme code
meme code@memecode
24 Apr 20:55

Фіксимо minikube на Mac з М1 (відмовляємось від qemu, запускаємо на docker)

meme code
meme code@memecode
Where can I find the older version of Google Chrome and download it? On the example of an old Mac
25 Apr 23:02

Where can I find the older version of Google Chrome and download it? On the example of an old Mac

meme code
meme code@memecode
09 May 19:27

[FIXED] cannot load such file -- html/pipeline (LoadError) виникає під час rails generate thredded:install

meme code
meme code@memecode
Задача на перевірку правильності розстановки дужок (Ruby)
21 May 10:27

Задача на перевірку правильності розстановки дужок (Ruby)

meme code
meme code@memecode
Як знайти підмасив з максимальною сумою (Maximum Subarray Sum) в Ruby
22 May 11:01

Як знайти підмасив з максимальною сумою (Maximum Subarray Sum) в Ruby

meme code
meme code@memecode
Google Ads for Dummies: A Step-by-Step Guide to a Successful Start
28 May 10:21

Google Ads for Dummies: A Step-by-Step Guide to a Successful Start

meme code
meme code@memecode
What jemalloc is and how it relates to Ruby /Ruby on Rails
30 May 11:53

What jemalloc is and how it relates to Ruby /Ruby on Rails

meme code
meme code@memecode
05 Jun 01:52

[Fixed] uninitialized constant ActiveSupport::LoggerThreadSafeLevel::Logger (NameError)

meme code
meme code@memecode
The preview in the network tab became very small after updating Chrome
05 Jun 18:23

The preview in the network tab became very small after updating Chrome

meme code
meme code@memecode