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

Task: Convert a Roman numeral to decimal (Ruby)

Post cover: Task: Convert a Roman numeral to decimal (Ruby)
This content has been automatically translated from Ukrainian.
Let's consider a simple solution to the problem of converting a Roman numeral to a decimal (Ruby).

Condition

Create a function solution that takes a string — a Roman numeral — and returns its value as a decimal integer.
No validation of the correctness of the Roman notation is needed.
Examples:
  • "MCMXC" → 1990
  • "MMVIII" → 2008
  • "MDCLXVI" → 1666

How does the conversion of Roman numerals to decimals work?

Roman numerals are a numeral system based on symbols, each corresponding to a specific value: I — 1, V — 5, X — 10, L — 50, C — 100, D — 500, M — 1000. To write a number, the symbols are combined according to certain rules. If a symbol of lesser value stands before a greater one (for example, IV), it means subtraction (5 - 1 = 4). If the opposite is true, they are added (VI = 5 + 1 = 6). This logic allows for compact representation of both simple and complex numbers, such as MCMXC for 1990.
When converting Roman numerals to decimals, the computer algorithm processes the string's characters from right to left. This makes it easy to determine whether to add or subtract the value of the symbol. For example, in XIV, processing starts with V = 5, then I = 1 (less than V, so we subtract: 5 - 1 = 4), then X = 10 (greater than I, so we add: 10 + 4 = 14). This approach allows for efficient implementation of the conversion even in a few lines of code.

Test (rspec) to check the method

RSpec.describe '#solution' do
  it 'converts simple Roman numerals' do
    expect(solution('I')).to eq(1)
    expect(solution('III')).to eq(3)
    expect(solution('VIII')).to eq(8)
  end

  it 'converts compound Roman numerals' 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 'converts large Roman numerals' 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

Method solution

One of the solutions (using Ruby, the same things can be done in many ways).
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

How the algorithm works

We move from the end of the string, adding the values of the symbols. If the current number is less than the previous one — we subtract it, otherwise — we add it. This allows for correct handling of cases like IV or 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

Fixing minikube "You are trying to run the amd64 binary on an M1 system."

meme code
meme code@memecode
24 Apr 20:55

Setting up minikube on Mac with M1 (abandoning qemu, running on docker)

meme code
meme code@memecode
Where to find an older version of Google Chrome and download it? Using an old Mac as an example.
25 Apr 23:02

Where to find an older version of Google Chrome and download it? Using an old Mac as an example.

meme code
meme code@memecode
09 May 19:27

[FIXED] cannot load such file -- html/pipeline (LoadError) occurs during rails generate thredded:install

meme code
meme code@memecode
Task to check the correctness of bracket placement (Ruby)
21 May 10:27

Task to check the correctness of bracket placement (Ruby)

meme code
meme code@memecode
How to find the maximum subarray sum in Ruby
22 May 11:01

How to find the maximum subarray sum in Ruby

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

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

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

What is jemalloc and how does it relate 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 after the Chrome update has become very small.
05 Jun 18:23

The preview in the network tab after the Chrome update has become very small.

meme code
meme code@memecode