Example #1
0
 /// <summary>
 /// Retrieve a letter lookup dictionary for a given calculation method
 /// </summary>
 /// <param name="type">The <see cref="GematriaType"/> for which to retrieve the lookup dictionary</param>
 /// <returns>Lookup dictionary giving the numeric value for each Hebew character</returns>
 public static Dictionary <char, int> GetDictionary(GematriaType type)
 {
     // only need to generate each type of dictionary once
     if (!lookupDict.ContainsKey(type))
     {
         lock (dictLock)
         {
             if (!lookupDict.ContainsKey(type))
             {
                 lookupDict[type] = GenerateDictionary(type);
             }
         }
     }
     return(lookupDict[type]);
 }
Example #2
0
        /// <summary>
        /// Calculates the gematria value for all Hebrew letters in the given string.
        /// Ignores all characters that are not Hebrew letters.
        /// </summary>
        /// <param name="sourceString">String to evaluate</param>
        /// <param name="gematriaType"><see cref="T:EllisWeb.Gematria.GematriaType"/> to use for calculation (defaults to Absolute)</param>
        /// <returns></returns>
        public static long GetGematriaValue(string sourceString, GematriaType gematriaType = GematriaType.Absolute)
        {
            if (string.IsNullOrEmpty(sourceString))
            {
                throw new ArgumentNullException("sourceString");
            }
            long value = 0;
            var  dict  = LookupFactory.GetDictionary(gematriaType);

            foreach (char c in sourceString)
            {
                if (dict.ContainsKey(c))
                {
                    value += dict[c];
                }
            }
            return(value);
        }
Example #3
0
        private static Dictionary <char, int> GenerateDictionary(GematriaType type)
        {
            Dictionary <char, int> dict;

            if (type == GematriaType.Absolute)
            {
                dict = new Dictionary <char, int>();
                dict.Add('א', 1);
                dict.Add('ב', 2);
                dict.Add('ג', 3);
                dict.Add('ד', 4);
                dict.Add('ה', 5);
                dict.Add('ו', 6);
                dict.Add('ז', 7);
                dict.Add('ח', 8);
                dict.Add('ט', 9);
                dict.Add('י', 10);
                dict.Add('כ', 20);
                dict.Add('ל', 30);
                dict.Add('מ', 40);
                dict.Add('נ', 50);
                dict.Add('ס', 60);
                dict.Add('ע', 70);
                dict.Add('פ', 80);
                dict.Add('צ', 90);
                dict.Add('ק', 100);
                dict.Add('ר', 200);
                dict.Add('ש', 300);
                dict.Add('ת', 400);
                dict.Add('ך', 20);
                dict.Add('ם', 40);
                dict.Add('ן', 50);
                dict.Add('ף', 80);
                dict.Add('ץ', 90);
            }
            else // start by calculating the Absolute method. All other methods can be derived from this.
            {
                dict = new Dictionary <char, int>(GenerateDictionary(GematriaType.Absolute));
                switch (type)
                {
                case GematriaType.AbsoluteAlternate:
                    // copy contents of absolute dict
                    // just switch the sofiyot
                    dict['ך'] = 500;
                    dict['ם'] = 600;
                    dict['ן'] = 700;
                    dict['ף'] = 800;
                    dict['ץ'] = 900;
                    break;

                case GematriaType.AbsoluteNoSofiyot:
                    dict.Remove('ך');
                    dict.Remove('ם');
                    dict.Remove('ן');
                    dict.Remove('ף');
                    dict.Remove('ץ');
                    break;

                case GematriaType.Reduced:
                    // copy contents of alternate dict
                    dict = new Dictionary <char, int>(GenerateDictionary(GematriaType.AbsoluteAlternate));

                    // go through all items and set to mod 10 of existing value
                    var keysToModify = dict.Where(x => x.Value > 9).Select(x => x.Key).ToList();
                    foreach (char itemKey in keysToModify)
                    {
                        var val = dict[itemKey];
                        if (val % 100 == 0)   // hundreds
                        {
                            val = val / 100;
                        }
                        else if (val % 10 == 0)   // tens
                        {
                            val = val / 10;
                        }
                        // if is not multiple of 10, then is in range of 1-9, so just use the number
                        dict[itemKey] = val;
                    }
                    break;

                case GematriaType.Ordinal:
                    int index = 1;
                    keysToModify = dict.Select(x => x.Key).ToList();
                    foreach (char key in keysToModify)
                    {
                        dict[key] = index++;
                    }
                    break;
                }
            }
            return(dict);
        }
Example #4
0
        /// <summary>
        /// Calculates the gematria value for a string that is intended to represent a number (example: a year in the Hebrew calendar or page in a Hebrew book).
        /// This function expects that the given string will contain only one word, and will throw an error if more than one word is included
        /// (this is because a string of Hebrew characters representing a number will never consist of multiple words).
        /// Ignores non-Hebrew characters and punctuation in the given word.
        /// </summary>
        /// <param name="sourceString">The string to evaluate</param>
        /// <param name="gematriaType"><see cref="T:EllisWeb.Gematria.GematriaType"/> to use for calculation (defaults to Absolute)</param>
        /// <param name="isStrictMode">
        /// Should the numeric gematria be evaluated with Strict Mode turned on. Defaults to the global setting
        /// defined in <see cref="ForceNumericStrictMode"/>. When true this will throw a <see cref="FormatException"/> whenever the numbers at
        /// the end of the string that are under 100 (ק) are not included in descending numeric order, and do not appear on the exceptions list.
        /// </param>
        /// <returns>Number equal to the numeric gematria value of the string provided</returns>
        /// <remarks>
        /// This function will infer the division between thousands-groupings of the number by using the following rule:
        /// Evaluate characters one at a time. It is expected that gematria values within a thousands-grouping will always be the same or equal to the previous value.
        /// If a value is encountered that is greater than the previous value, it signifies the start of a new thousands-grouping.
        /// </remarks>
        public static long GetNumericGematriaValue(string sourceString, GematriaType gematriaType = GematriaType.Absolute, bool?isStrictMode = null)
        {
            sourceString = sourceString.Trim();

            bool currentStrictMode = isStrictMode ?? ForceNumericStrictMode;

            if (currentStrictMode)
            {
                var stripped = StripSeparatorCharacters(sourceString);
                if (KnownNumericValues.ContainsKey(stripped))
                {
                    return(KnownNumericValues[stripped]);
                }
            }

            if (Regex.IsMatch(sourceString, @"[\s]"))
            {
                throw new ArgumentException("Source string contains more than one word", "sourceString");
            }

            var dict = LookupFactory.GetDictionary(gematriaType);

            List <List <int> > numberStacks = new List <List <int> >();
            var currentStack = new List <int>();

            numberStacks.Add(currentStack);

            int prevNum = 0;

            foreach (char c in sourceString)
            {
                if (dict.ContainsKey(c))
                {
                    int currentVal = dict[c];
                    if (currentVal > prevNum && currentStack.Any())
                    {
                        currentStack = new List <int>();
                        numberStacks.Add(currentStack);
                    }
                    currentStack.Add(currentVal);
                    prevNum = currentVal;
                }
            }

            // At this point, the first number stack is the highest thousands-grouping. Need to reverse them in order to go from lowest to highest when evaluating.
            numberStacks.Reverse();

            // Go through the number stacks. Multiply the sum of each stack by 1000^X where X is the zero-index value of the current stack
            int  currentStackIndex = 0;
            long value             = 0;
            bool inHundreds        = false;
            long maxStackSum       = 0;

            foreach (List <int> numberStack in numberStacks)
            {
                long stackSum = numberStack.Sum();
                if (currentStrictMode)
                {
                    numberStack.Reverse(); // need to reverse the current stack, in order to preserve the order of items being evaluated
                    foreach (var number in numberStack)
                    {
                        if (number >= 100)
                        {
                            inHundreds = true;
                        }
                        if (!inHundreds && number < maxStackSum)
                        {
                            throw new FormatException("In Strict Mode, trailing values less than 100 (ק) must appear in the proper order");
                        }
                        maxStackSum = Math.Max(maxStackSum, number);
                    }
                }
                var stackMultiplier  = Math.Pow(1000, currentStackIndex++);
                var adjustedStackSum = Convert.ToInt64(stackSum * stackMultiplier);
                value += adjustedStackSum;
            }

            return(value);
        }