Цейво!Всі публікаціїКатегоріїПро проєктДопомогти Україні 🇺🇦

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

Обкладинка допису: Задача: Перетворення римського числа на десяткове (Ruby)
Розглянемо простий варіант вирішення задачі по перетворенню римського числа на десяткове (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.

Цей допис поки що не має жодних доповнень від автора/ки.

[Codecov] В чому різниця між patch та project coverage?
09 квіт., 16:03

[Codecov] В чому різниця між patch та project coverage?

meme code
meme code@memecode
Як курси Scratch допомагають дітям розвивати soft skills?
11 квіт., 18:24

Як курси Scratch допомагають дітям розвивати soft skills?

meme code
meme code@memecode
24 квіт., 20:17

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

meme code
meme code@memecode
24 квіт., 20:55

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

meme code
meme code@memecode
Де знайти старішу версію Google Chrome та скачати її? На прикладі старого Mac
25 квіт., 23:02

Де знайти старішу версію Google Chrome та скачати її? На прикладі старого Mac

meme code
meme code@memecode
09 трав., 19:27

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

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

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

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

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

meme code
meme code@memecode
Реклама в Google для чайників: Покроковий гід для успішного старту
28 трав., 10:21

Реклама в Google для чайників: Покроковий гід для успішного старту

meme code
meme code@memecode
Що таке jemalloc і як він стосується Ruby / Ruby on Rails
30 трав., 11:53

Що таке jemalloc і як він стосується Ruby / Ruby on Rails

meme code
meme code@memecode
05 черв., 01:52

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

meme code
meme code@memecode
Прев'ю у network вкладці після оновлення Chrome стало дуже мале
05 черв., 18:23

Прев'ю у network вкладці після оновлення Chrome стало дуже мале

meme code
meme code@memecode