示例#1
0
文件: Validate.cs 项目: IDjinn/Romano
        private static Exception?CheckRepeatedDigits(string roman, RomanizerOptions options)
        {
            var allowFourSum     = options.HasFlag(RomanizerOptions.ALLOW_FOUR_SEQUENTIAL_DIGITS);
            var allowMultipleSum = options.HasFlag(RomanizerOptions.ALLOW_MULTIPLE_SEQUENTIAL_DIGITS);

            for (var i = 0; i < roman.Length; i++)
            {
                var current       = roman[i];
                var totalRepeated = (byte)roman.Skip(i).TakeWhile(digit => digit == current).Count();
                switch (totalRepeated)
                {
                case <= 3:
                    continue;

                case 4 when !allowFourSum:
                    return(new ArithmeticAdditionException(
                               roman, current, totalRepeated,
                               $"Roman number '{roman}' with multiple repeated digits of '{current}' with total '{totalRepeated}', so it is invalid roman number. If you want sum 4 digits you need allow this in options entry."));

                case > 4 when !allowMultipleSum:
                    return(new ArithmeticAdditionException(
                               roman, current, totalRepeated,
                               $"Roman number '{roman}' with multiple repeated digits of '{current}' with total '{totalRepeated}', so it is invalid roman number. If you want sum more than 4 digits you need allow this in options entry."));
                }
            }

            return(null);
        }
示例#2
0
        internal static string RomanizeUnsafe(ushort number, RomanizerOptions options = RomanizerOptions.DEFAULT_STRICT)
        {
            StringBuilder roman = new(MAX_VALUE_ROMAN.Length);

            do
            {
                for (var i = 0; i < romanNumbersReversed.Count(); i++)
                {
                    var(romanDigit, decimalDigit) = romanNumbersReversed.ElementAt(i);
                    if (number < decimalDigit)
                    {
                        continue;
                    }

                    var count = (ushort)Math.Round((double)(number / decimalDigit));

                    /*
                     * Special rule
                     *
                     * When the number have free 4 units, need subtract then by higher value for not throw 4 sum limit.
                     *
                     * Example: IIII => IV
                     */
                    var isSpecialCountRule = count == 4 && !options.HasFlag(RomanizerOptions.ALLOW_FOUR_SEQUENTIAL_DIGITS);
                    if (isSpecialCountRule)
                    {
                        var higherValueIndex = i - 1;
                        var(rightRomanDigit, rightDigit) = romanNumbersReversed.ElementAtOrDefault(higherValueIndex);
                        var existRightValue = rightRomanDigit != 0 && rightDigit > 0;

                        /*
                         * Need check if have higher value to subtract free units
                         */
                        if (existRightValue)
                        {
                            roman.Append(romanDigit);
                            roman.Append(rightRomanDigit);
                            number -= (ushort)(decimalDigit * count);
                            break;
                        }
                    }

                    /*
                     * Special rule end
                     */

                    for (var j = 0; j < count; j++)
                    {
                        roman.Append(romanDigit);
                    }
                    number -= (ushort)(decimalDigit * count);
                    break;
                }
            } while (number > 0);

            return(roman.ToString());
        }
示例#3
0
        private static void CheckSpecialRules(char left, char right, char current, int rightValue,
                                              RomanizerOptions options)
        {
            var isNotStrict = !options.HasFlag(RomanizerOptions.DEFAULT_STRICT);

            if (isNotStrict)
            {
                return;
            }

            var isAddition = Util.ConvertSingleRomanToDecimal(current) >= rightValue;

            if (isAddition)
            {
                CheckAdditionSpecialRules(current, rightValue, options);
            }
            else
            {
                CheckSubtractionSpecialRules(left, right, current, options);
            }
        }