Esempio n. 1
0
        static void Main(string[] args)
        {
            var assembly     = Assembly.GetExecutingAssembly();
            var resourceName = typeof(Program).Namespace + ".wordlist";

            string wordlist = "";

            using (Stream stream = assembly.GetManifestResourceStream(resourceName))
                using (StreamReader reader = new StreamReader(stream))
                {
                    wordlist = reader.ReadToEnd();
                }

            try
            {
                WordManager manager = new WordManager();
                manager.ReadWordsFrom(wordlist);
                using (AnagramFinder finder = new AnagramFinder(manager))
                {
                    finder.FindAnagrams("e4820b45d2277f3844eac66c903e84be",
                                        "23170acc097c24edb98fc5488ab033fe",
                                        "665e5bcb0c20062fe8abaaf4628bb154");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error occured: {0}", ex.Message);
                Console.WriteLine("Stack: {0}", ex.StackTrace);
            }

            Console.WriteLine("Enter any key to exit...");
            Console.ReadLine();
        }
Esempio n. 2
0
        private void FindAnagramResult_2W(Stopwatch sw)
        {
            IDictionary <int, WordNode> combinations = new Dictionary <int, WordNode>();

            try
            {
                sw.Start();
                Console.WriteLine("Looking at 2 word anagrams...");

                // step 1, pick A
                foreach (Word word in manager.Words.Values)
                {
                    // picking A, 9+ only
                    if (word.Power < 9)
                    {
                        continue;
                    }

                    combinations.Add(word.Code, new WordNode(word));
                }

                // step 2, pick B
                foreach (KeyValuePair <int, WordNode> wordInfo in combinations)
                {
                    int max = WordManager.Max;
                    // current holds B
                    int current = WordManager.SubtractCode(max, wordInfo.Key);

                    if (!manager.Words.ContainsKey(current))
                    {
                        continue;
                    }
                    wordInfo.Value.ChildNodes.Add(current, new WordNode(manager.Words[current]));
                }

                Permutation permof2Words = new Permutation(2);

                // brute force build sentences, too lazy to check in a sophisticated manner as remaining result set is not huge
                foreach (WordNode nodeA in combinations.Values)
                {
                    foreach (WordNode nodeB in nodeA.ChildNodes.Values)
                    {
                        foreach (string wordA in nodeA.WordRef.Words)
                        {
                            foreach (string wordB in nodeB.WordRef.Words)
                            {
                                // build sentences and get hashcode
                                CalculateHashOfSentencePermutations(permof2Words, wordA, wordB);
                            }
                        }
                    }
                }
            }
            finally
            {
                Console.WriteLine("Looking at 2 word anagrams... took {0}", sw.Elapsed.ToString());
            }
        }
Esempio n. 3
0
 public Word(int code)
 {
     Code  = code;
     Power = WordManager.PowerOfWordCode(code);
 }
Esempio n. 4
0
        private void FindAnagramResult_4W(Stopwatch sw)
        {
            IDictionary <int, WordNode> combinations = new Dictionary <int, WordNode>();

            try
            {
                sw.Start();
                Console.WriteLine("Looking at 4 word anagrams...");

                // step 1, pick A
                foreach (Word word in manager.Words.Values)
                {
                    // picking A, 5+ only
                    if (word.Power < 5)
                    {
                        continue;
                    }

                    combinations.Add(word.Code, new WordNode(word));
                }

                // step 2, pick B for every A
                foreach (WordNode nodeA in combinations.Values)
                {
                    int max = WordManager.Max;
                    // current holds potential of B+C+D
                    int current = WordManager.SubtractCode(max, nodeA.WordRef.Code);

                    int powerofA    = WordManager.PowerOfWordCode(nodeA.WordRef.Code);
                    int maxpowerofB = Math.Min(powerofA, WordManager.MaxPower - powerofA);
                    int minpowerofB = Convert.ToInt32(Math.Ceiling(((float)(WordManager.MaxPower - powerofA)) / 3));

                    foreach (int possibleB in manager.FindWords(current, maxpowerofB, minpowerofB))
                    {
                        nodeA.ChildNodes.Add(possibleB, new WordNode(manager.Words[possibleB]));
                    }
                }

                // step 3, pick C for every A + B
                foreach (WordNode nodeA in combinations.Values)
                {
                    foreach (WordNode nodeB in nodeA.ChildNodes.Values)
                    {
                        int max = WordManager.Max;
                        // current holds potential of C+D
                        int current = WordManager.SubtractCode(max, nodeA.WordRef.Code);
                        current = WordManager.SubtractCode(current, nodeB.WordRef.Code);
                        int currentpower = WordManager.PowerOfWordCode(current);

                        int powerofB    = WordManager.PowerOfWordCode(nodeB.WordRef.Code);
                        int maxpowerofC = Math.Min(powerofB, WordManager.MaxPower - powerofB);
                        int minpowerofC = Convert.ToInt32(Math.Ceiling(((float)currentpower) / 2));

                        foreach (int possibleC in manager.FindWords(current, maxpowerofC, minpowerofC))
                        {
                            // prevents 3W sentences
                            if (possibleC == current)
                            {
                                continue;
                            }
                            nodeB.ChildNodes.Add(possibleC, new WordNode(manager.Words[possibleC]));
                        }
                    }
                }

                Permutation permof4Words = new Permutation(4);

                // brute force 4 word sentence hash checking
                foreach (WordNode nodeA in combinations.Values)
                {
                    foreach (WordNode nodeB in nodeA.ChildNodes.Values)
                    {
                        foreach (WordNode nodeC in nodeB.ChildNodes.Values)
                        {
                            int temp = WordManager.Max;
                            temp = WordManager.SubtractCode(temp, nodeA.WordRef.Code);
                            temp = WordManager.SubtractCode(temp, nodeB.WordRef.Code);
                            temp = WordManager.SubtractCode(temp, nodeC.WordRef.Code);

                            // not interested in 3W
                            if (temp == 0)
                            {
                                continue;
                            }

                            // A+B+C left no D available
                            if (!manager.Words.ContainsKey(temp))
                            {
                                continue;
                            }

                            foreach (string wordA in nodeA.WordRef.Words)
                            {
                                foreach (string wordB in nodeB.WordRef.Words)
                                {
                                    foreach (string wordC in nodeC.WordRef.Words)
                                    {
                                        foreach (string wordD in manager.Words[temp].Words)
                                        {
                                            CalculateHashOfSentencePermutations(permof4Words, wordA, wordB, wordC, wordD);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                Console.WriteLine("Looking at 4 word anagrams... took {0}", sw.Elapsed.ToString());
            }
        }
Esempio n. 5
0
 public AnagramFinder(WordManager words, params string[] hashes)
 {
     manager = words;
     md5     = MD5.Create();
 }
Esempio n. 6
0
        private void FindAnagramResult_3W(Stopwatch sw)
        {
            IDictionary <int, WordNode> combinations = new Dictionary <int, WordNode>();

            try
            {
                sw.Start();
                Console.WriteLine("Looking at 3 word anagrams...");

                // step 1, pick A
                foreach (Word word in manager.Words.Values)
                {
                    // picking A, 6+ only
                    if (word.Power < 6)
                    {
                        continue;
                    }

                    combinations.Add(word.Code, new WordNode(word));
                }

                // step 2, pick B
                foreach (KeyValuePair <int, WordNode> wordInfo in combinations)
                {
                    int max = WordManager.Max;
                    // current holds potential of B and C
                    int current     = WordManager.SubtractCode(max, wordInfo.Key);
                    int powerofA    = WordManager.PowerOfWordCode(wordInfo.Key);
                    int maxpowerofB = Math.Min(powerofA, max - powerofA);
                    int minpowerofB = Convert.ToInt32(Math.Ceiling(((float)(WordManager.MaxPower - powerofA)) / 2));

                    foreach (int possibleB in manager.FindWords(current, maxpowerofB, minpowerofB))
                    {
                        wordInfo.Value.ChildNodes.Add(possibleB, new WordNode(manager.Words[possibleB]));
                    }
                }

                // step 3.a, filter out invalid combinations of A+B, A+B left no possible C, check will allow possible A+B without a C
                foreach (int wordA in combinations.Keys)
                {
                    WordNode possibleB = combinations[wordA];
                    foreach (int wordB in possibleB.ChildNodes.Keys.ToArray())
                    {
                        int max  = WordManager.Max;
                        int temp = WordManager.SubtractCode(max, wordA);
                        temp = WordManager.SubtractCode(temp, wordB);

                        if (!manager.Words.ContainsKey(temp))
                        {
                            possibleB.ChildNodes.Remove(wordB);
                        }

                        int powerA = WordManager.PowerOfWordCode(wordA);
                        int powerB = WordManager.PowerOfWordCode(wordB);
                        int powerC = WordManager.PowerOfWordCode(temp);

                        // if total length is not 18 then we missed letters in anagram, lets fail with exc
                        if (powerA + powerB + powerC != WordManager.MaxPower)
                        {
                            throw new InvalidOperationException("Algorithm has a length bug! Words A B C cannot make 18 characters");
                        }
                    }
                }

                // step 3.b, filter out invalid combinations of A+B, A has no B because it used all good letters perhaps
                foreach (int key in combinations.Keys.ToArray())
                {
                    if (combinations[key].ChildNodes.Count == 0)
                    {
                        combinations.Remove(key);
                    }
                }

                Permutation permof3Words = new Permutation(3);

                // brute force build sentences, too lazy to check in a sophisticated manner as remaining result set is not huge
                foreach (WordNode nodeA in combinations.Values)
                {
                    foreach (WordNode nodeB in nodeA.ChildNodes.Values)
                    {
                        int max   = WordManager.Max;
                        int codeC = WordManager.SubtractCode(max, nodeA.WordRef.Code);
                        codeC = WordManager.SubtractCode(codeC, nodeB.WordRef.Code);

                        foreach (string wordA in nodeA.WordRef.Words)
                        {
                            foreach (string wordB in nodeB.WordRef.Words)
                            {
                                foreach (string wordC in manager.Words[codeC].Words)
                                {
                                    // build sentences and get hashcode
                                    CalculateHashOfSentencePermutations(permof3Words, wordA, wordB, wordC);
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                Console.WriteLine("Looking at 3 word anagrams... took {0}", sw.Elapsed.ToString());
            }
        }