Commit f36eae6d authored by Illia Baida's avatar Illia Baida

Roman to Decimal (ready to test)

parent 8f4a9598
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
text-align: center; text-align: center;
} }
.App input {
font-size: 14px;
width: 250px;
}
.App-logo { .App-logo {
height: 10vmin; height: 10vmin;
pointer-events: none; pointer-events: none;
......
import React, { useEffect, useCallback, useState, useMemo } from "react"; import React, { useEffect, useCallback, useState, useMemo } from "react";
import logo from "./logo.svg"; import logo from "./logo.svg";
import "./App.css"; import "./App.css";
import Converter from './helper/converter'; import Converter from "./helper/converter";
const Inputs = { toDecimal: "toDecimal", toRoman: "toRoman" }; const Inputs = { toDecimal: "toDecimal", toRoman: "toRoman" };
...@@ -27,27 +27,36 @@ function App() { ...@@ -27,27 +27,36 @@ function App() {
}, [toDecimalValue, toRomanValue]); }, [toDecimalValue, toRomanValue]);
// convert values // convert values
const converted = useMemo(() => { const convertedDecimal = useMemo(() => {
const romanToBeConverted = toDecimalValue; const romanToBeConverted = toDecimalValue;
return Converter.fromRoman(romanToBeConverted);
}, [toDecimalValue]);
const convertedRoman = useMemo(() => {
const decimalToBeConverted = toRomanValue; const decimalToBeConverted = toRomanValue;
return { return Converter.toRoman(decimalToBeConverted);
toDecimal: Converter.fromRoman(romanToBeConverted), }, [toRomanValue]);
toRoman: Converter.toRoman(decimalToBeConverted)
};
}, [toDecimalValue, toRomanValue]);
return ( return (
<div className="App"> <div className="App">
<header className="App-header"> <header className="App-header">
<img src={logo} className="App-logo" alt="logo" /> <img src={logo} className="App-logo" alt="logo" />
<p>Available range: from 1 to 3999</p> <p>{`Available range: from ${Converter.decimalLimit[0]} to ${Converter.decimalLimit[1]}`}</p>
<h3>Converter: Roman to Decimal</h3> <h3>Converter: Roman to Decimal</h3>
<input name={Inputs.toDecimal} onChange={handleChange} /> <input
<span>Value is: {converted.toDecimal}</span> name={Inputs.toDecimal}
onChange={handleChange}
placeholder="Enter Roman number here"
/>
<span>Decimal value is: {convertedDecimal}</span>
<span>---</span>
<h3>Converter: Decimal to Roman</h3> <h3>Converter: Decimal to Roman</h3>
<input name={Inputs.toRoman} onChange={handleChange} /> <input
<span>Value is: {converted.toRoman}</span> name={Inputs.toRoman}
onChange={handleChange}
placeholder="Enter Decimal number here"
/>
<span>Roman value is: {convertedRoman}</span>
</header> </header>
</div> </div>
); );
......
export default class Converter { export default class Converter {
// NOTE: there is possible to extend Dictionary: first Add new <letter> : <value> pair then update decimalLimit array
static decimalLimit = [1, 3999];
static Dictionary = { static Dictionary = {
I: 1, I: 1,
V: 5, V: 5,
...@@ -6,7 +8,9 @@ export default class Converter { ...@@ -6,7 +8,9 @@ export default class Converter {
L: 50, L: 50,
C: 100, C: 100,
D: 500, D: 500,
M: 1000 M: 1000,
// K: 5000, // extend Dictionary by adding at least 2 new pairs
// F: 10000,
}; };
static _dictionaryValues = Object.values(this.Dictionary).reverse(); static _dictionaryValues = Object.values(this.Dictionary).reverse();
...@@ -61,8 +65,6 @@ export default class Converter { ...@@ -61,8 +65,6 @@ export default class Converter {
return dictionary; return dictionary;
} }
static _formatExpression() {}
static _multiplyString(str, times) { static _multiplyString(str, times) {
let res = ""; let res = "";
for (let i = 0; i < times; i++) { for (let i = 0; i < times; i++) {
...@@ -74,7 +76,11 @@ export default class Converter { ...@@ -74,7 +76,11 @@ export default class Converter {
static toRoman(decimalValue) { static toRoman(decimalValue) {
let romanExpression = ""; let romanExpression = "";
this._decimalToPropagate = decimalValue; this._decimalToPropagate = +decimalValue;
if(this._decimalToPropagate < this.decimalLimit[0] || this._decimalToPropagate > this.decimalLimit[1]){
return '[Validation error: invalid range]'
}
const calculatedDictionary = this._dictionaryNames.reduce( const calculatedDictionary = this._dictionaryNames.reduce(
(dictionary, sign) => this._extractMultiple(sign, dictionary), (dictionary, sign) => this._extractMultiple(sign, dictionary),
...@@ -149,20 +155,40 @@ export default class Converter { ...@@ -149,20 +155,40 @@ export default class Converter {
let result = 0; let result = 0;
const signs = romanExpression.split(""); const signs = romanExpression.split("");
const validated = signs.every(s => this._validateSign(s));
if(!validated){
return '[Validation error]'
}
for (let seqIndex = 0; seqIndex < signs.length; ) { for (let seqIndex = 0; seqIndex < signs.length; ) {
const currentSign = signs[seqIndex]; const currentSign = signs[seqIndex];
const upperDictionarySign = this._dictionaryNames[ const upperDictionarySign = this._dictionaryNames[
this._dictionaryNames.indexOf(currentSign) - 1 this._dictionaryNames.indexOf(currentSign) - 1
]; ];
const upperDictionaryDecimalGroupSign = this._dictionaryNames[
this._dictionaryNames.indexOf(currentSign) - 2
];
if (upperDictionarySign === signs[seqIndex + 1]) { if (upperDictionarySign && upperDictionarySign === signs[seqIndex + 1]) {
// records like IX CD CM XL // records like IV CD XL
const representChunk = const representChunk =
this.Dictionary[upperDictionarySign] - this.Dictionary[currentSign]; this.Dictionary[upperDictionarySign] - this.Dictionary[currentSign];
result += representChunk; result += representChunk;
seqIndex++; seqIndex += 2;
} else if (
upperDictionarySign &&
this._isSignDescribesDecimalGroup(currentSign) &&
upperDictionaryDecimalGroupSign === signs[seqIndex + 1]
) {
// records like IX CM XC
const representChunk =
this.Dictionary[upperDictionaryDecimalGroupSign] -
this.Dictionary[currentSign];
result += representChunk;
seqIndex += 2;
} else { } else {
// records like CCC XX III // records like CCC XX III X I
const timesToMultiply = this._extractSeqSameSigns( const timesToMultiply = this._extractSeqSameSigns(
signs, signs,
currentSign, currentSign,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment