/// <summary> /// Convert roman number to integer /// </summary> /// <returns>Integer</returns> /// <param name="numberStr">Roman number</param> public static int RomanToArabic(this string numberStr) { if (String.IsNullOrWhiteSpace(numberStr)) { throw new ArgumentException("Invalid number provided."); } int res = 0; bool isLastDigit = false; bool skipNextDigit = false; var chars = numberStr.ToCharArray(); for (int i = 0; i < chars.Count(); i++) { if (skipNextDigit) { skipNextDigit = false; continue; } RomanNumberSymbol currentSymbol = GetRomanSymbol(chars.ElementAt(i)); isLastDigit = i == chars.Count() - 1; int currentNumber = 0; RomanNumberSymbol?nextSymbol = (isLastDigit) ? (RomanNumberSymbol?)null : GetRomanSymbol(chars.ElementAt(i + 1)); if (!isLastDigit && nextSymbol.HasValue && IsSpecialCase(currentSymbol, nextSymbol.Value)) { currentNumber = (int)nextSymbol - (int)currentSymbol; skipNextDigit = true; } else { currentNumber = (int)currentSymbol; } res += currentNumber; } return(res); }
private static void AppendDigits(ref int number, RomanNumberSymbol romanDigit, StringBuilder str) { decimal digitsCount = number / (decimal)romanDigit; if (digitsCount < 0) { return; } int subtrahend = (int)(Math.Floor(digitsCount) * (int)romanDigit); number -= subtrahend; int intCount = (int)Math.Floor(digitsCount); for (int i = 0; i < intCount; i++) { str.Append(romanDigit.ToString()); } }
private static bool IsSpecialCase(RomanNumberSymbol first, RomanNumberSymbol second) { if (first == second || first > second) { return(false); } if (first == RomanNumberSymbol.I && second == RomanNumberSymbol.V || first == RomanNumberSymbol.I && second == RomanNumberSymbol.X || first == RomanNumberSymbol.X && second == RomanNumberSymbol.L || first == RomanNumberSymbol.X && second == RomanNumberSymbol.C || first == RomanNumberSymbol.C && second == RomanNumberSymbol.D || first == RomanNumberSymbol.C && second == RomanNumberSymbol.M) { return(true); } throw new ArgumentException("Invalid Roman digit composition. Roman digits in numbers generally go from highest to lowest, " + "only exception beeing 6 special cases when it's used for brevity, e.g. IV instead of IIII."); }