Converting Integers to Roman Numerals on the Blockchain with Solidity

Rohit Goyal
Coinmonks

--

Roman numerals are a historical numeral system that originated in ancient Rome. While not as commonly used today, they still hold cultural and historical significance. Imagine you are tasked with creating a smart contract that converts integers to Roman numerals within a blockchain context. Let’s delve into how to achieve this using Solidity, a programming language for writing smart contracts on the Ethereum blockchain.

Introduction

In this blog post, we will explore a Solidity smart contract that can convert integers to their corresponding Roman numeral representation. This contract utilizes a loop and a set of predefined values to achieve the conversion. We will discuss the key components of the contract and explain its working.

Photo by Jievani Weerasinghe on Unsplash

The RomanNumber Smart Contract

The RomanNumber smart contract is designed to facilitate the conversion of integers to Roman numerals. Let's break down its key components:

Predefined Values

The contract starts by defining a set of predefined values for Roman numerals, ranging from M (1000) to I (1). These values are represented as constants using the uint256 data type.

contract RomanNumber {
uint256 M = 1000;
uint256 D = 500;
uint256 C = 100;
uint256 L = 50;
uint256 X = 10;
uint256 V = 5;
uint256 IV = 4;
uint256 IX = 9;
}

integerToRoman Function

The main function of the contract is integerToRoman, which takes an integer as input and returns its Roman numeral representation as a string. Here's how the function works:

It initializes a reminder variable with the input integer and prepares roman and joinRoman strings for constructing the final Roman numeral.

The function enters a loop where it iterates through the predefined values, checking if the reminder is greater than or equal to each value. If it is, the loop function loop is called to add the corresponding Roman numeral to joinRoman, and the reminder is updated accordingly.

For special cases like 4 (IV) and 9 (IX), the function directly assigns the corresponding Roman numerals and sets reminder to 0.

If none of the predefined values match the reminder, the function adds the appropriate number of "I" characters to joinRoman using the loop function.

The joinRoman is concatenated to the roman string.

Once the loop completes, the function returns the roman string containing the Roman numeral representation of the input integer.



function integerToRoman(uint256 _integer)
external
view
returns (string memory)
{
uint256 reminder = _integer;
string memory roman;
string memory joinRoman = "";
while (reminder != 0) {
if (reminder >= M) {
joinRoman = loop(reminder / M, "M");
reminder = reminder % M;
} else if (reminder >= D) {
joinRoman = loop(reminder / D, "D");
reminder = reminder % D;
} else if (reminder >= C) {
joinRoman = loop(reminder / C, "C");
reminder = reminder % C;
} else if (reminder >= L) {
joinRoman = loop(reminder / L, "L");
reminder = reminder % L;
} else if (reminder >= X) {
joinRoman = loop(reminder / X, "X");
reminder = reminder % X;
} else if (reminder == 4) {
joinRoman = "IV";
reminder = 0;
} else if (reminder == 9) {
joinRoman = "IX";
reminder = 0;
} else if (reminder >= V) {
joinRoman = loop(reminder / V, "V");
reminder = reminder % V;
} else {
joinRoman = loop(reminder, "I");
reminder = 0;
}

roman = string.concat(roman, joinRoman);
}
return roman;
}

loop Function

The loop function is a helper function used to concatenate a given Roman numeral a specific number of times based on the provided _number. This function is essential for constructing the Roman numerals during the conversion process.

function loop(uint256 _number, string memory _roman)
internal
pure
returns (string memory)
{
string memory joinRoman;
for (uint256 i = 0; i < _number; i++) {
joinRoman = string.concat(joinRoman, _roman);
}
return joinRoman;
}

Full Code

contract RomanNumber {
uint256 M = 1000;
uint256 D = 500;
uint256 C = 100;
uint256 L = 50;
uint256 X = 10;
uint256 V = 5;
uint256 IV = 4;
uint256 IX = 9;

function integerToRoman(uint256 _integer)
external
view
returns (string memory)
{
uint256 reminder = _integer;
string memory roman;
string memory joinRoman = "";
while (reminder != 0) {
if (reminder >= M) {
joinRoman = loop(reminder / M, "M");
reminder = reminder % M;
} else if (reminder >= D) {
joinRoman = loop(reminder / D, "D");
reminder = reminder % D;
} else if (reminder >= C) {
joinRoman = loop(reminder / C, "C");
reminder = reminder % C;
} else if (reminder >= L) {
joinRoman = loop(reminder / L, "L");
reminder = reminder % L;
} else if (reminder >= X) {
joinRoman = loop(reminder / X, "X");
reminder = reminder % X;
} else if (reminder == 4) {
joinRoman = "IV";
reminder = 0;
} else if (reminder == 9) {
joinRoman = "IX";
reminder = 0;
} else if (reminder >= V) {
joinRoman = loop(reminder / V, "V");
reminder = reminder % V;
} else {
joinRoman = loop(reminder, "I");
reminder = 0;
}
roman = string.concat(roman, joinRoman);
}
return roman;
}

function loop(uint256 _number, string memory _roman)
internal
pure
returns (string memory)
{
string memory joinRoman;
for (uint256 i = 0; i < _number; i++) {
joinRoman = string.concat(joinRoman, _roman);
}
return joinRoman;
}
}

Conclusion

The RomanNumber smart contract demonstrates how Solidity can be used to create a simple yet functional system for converting integers to Roman numerals. By leveraging predefined values and a loop, the contract efficiently constructs the Roman numeral representation of an integer input.

This example also highlights the versatility of Solidity beyond financial transactions. Smart contracts can be applied to various scenarios, from complex decentralized applications to novel utilities like this Roman numeral converter.

Remember that the example provided is simplified and does not account for all possible edge cases. When developing smart contracts for production environments, thorough testing and consideration of potential vulnerabilities are crucial.

Incorporating Roman numeral conversion into a blockchain setting not only showcases the flexibility of smart contracts but also adds a touch of historical flair to the world of decentralized applications.

--

--

Rohit Goyal
Coinmonks

I write some words that work for me. Primarily give Knowledge about Blockchain and smart contract coding tips. Also share personal life lessons.