Skip to content

Instantly share code, notes, and snippets.

@diademoff
Created September 3, 2021 12:04
Show Gist options
  • Save diademoff/5f06061826e75b45ba27e34c26098608 to your computer and use it in GitHub Desktop.
Save diademoff/5f06061826e75b45ba27e34c26098608 to your computer and use it in GitHub Desktop.
Convert to Roman number
using System;
using System.Collections.Generic;
using System.Linq;
public class RomanNumerals
{
struct NumberInfo
{
public int Value;
public int RangeBegin;
public int RangeEnd;
public int PowLen => RangeBegin.ToString().Length - 1;
public NumberInfo(int value, int rangeBegin, int rangeEnd)
{
Value = value;
RangeBegin = rangeBegin;
RangeEnd = rangeEnd;
}
public bool InRange(int n)
{
return (n >= RangeBegin) && (n <= RangeEnd);
}
}
static Dictionary<char, NumberInfo> numbers = new Dictionary<char, NumberInfo>(){
{'I', new NumberInfo(1, 1, 3)},
{'V', new NumberInfo(5, 4, 8)},
{'X', new NumberInfo(10, 9, 39)},
{'L', new NumberInfo(50, 40, 89)},
{'C', new NumberInfo(100, 90, 399)},
{'D', new NumberInfo(500, 400, 899)},
{'M', new NumberInfo(1000, 900, 4000)}
};
public static string ToRoman(int n)
{
if (n <= 3)
return new String(numbers.ElementAt(0).Key, n);
foreach (var i in numbers)
if (i.Value.InRange(n))
if (n % (int)Math.Pow(10, i.Value.PowLen) == 0 || n.ToString().Length == 1)
{
if (n < i.Value.Value)
return ToRoman(i.Value.Value - n) + i.Key;
else if (n == i.Value.Value)
return i.Key.ToString();
else if (n > i.Value.Value)
return i.Key + ToRoman(n - i.Value.Value);
}
else
return ToRoman(n - (n % (int)Math.Pow(10, i.Value.PowLen))) + ToRoman(n % (int)Math.Pow(10, i.Value.PowLen));
return "";
}
public static int FromRoman(string romanNumeral)
{
if (romanNumeral.Length == 1)
return numbers[romanNumeral[0]].Value;
if (string.IsNullOrWhiteSpace(romanNumeral))
return 0;
var bni = BiggestNumberIndex(romanNumeral);
var BiggestNumber = FromRoman(romanNumeral[bni].ToString());
var Before = FromRoman(romanNumeral.Substring(0, bni));
var After = bni == romanNumeral.Length - 1 ? 0 : FromRoman(romanNumeral.Substring(bni + 1));
return BiggestNumber - Before + After;
}
static int BiggestNumberIndex(string str)
{
int index = 0, number = 0;
for (int i = 0; i < str.Length; i++)
if (numbers[str[i]].Value > number)
{
index = i;
number = numbers[str[i]].Value;
}
return index;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment