private static CharEntryNode GetMin(List <CharEntryNode> charEntryNodes)
        {
            CharEntryNode minCharEntry = charEntryNodes
                                         .First(ce => ce.RepetitionsSum == charEntryNodes.Min(cen => cen.RepetitionsSum));

            charEntryNodes.Remove(minCharEntry);

            return(minCharEntry);
        }
        private static Dictionary <char, string> FormeEcryptingTable(CharEntryNode rootCharEntry,
                                                                     List <CharEntry> charEntries)
        {
            Dictionary <char, string> encryptingTable = charEntries
                                                        .ToDictionary(ce => ce.Character, ce => (string)null);

            FormEncodingTableInternal(encryptingTable, rootCharEntry, "");

            return(encryptingTable);
        }
        public static string Encrypt(string source)
        {
            char[] sourceCharacters = source.ToCharArray();

            List <CharEntry>          charEntries     = Parse(sourceCharacters);
            CharEntryNode             rootCharEntry   = FormTree(charEntries);
            Dictionary <char, string> encryptingTable = FormeEcryptingTable(rootCharEntry, charEntries);

            return(EncryptInternal(sourceCharacters, encryptingTable));
        }
        private static CharEntryNode FormTreeInternal(List <CharEntryNode> charEntryNodes)
        {
            while (charEntryNodes.Count() != 1)
            {
                CharEntryNode oneCharEntry = GetMin(charEntryNodes);
                CharEntryNode twoCharEntry = GetMin(charEntryNodes);

                CharEntryNode charEntryNode = new CharEntryNode(oneCharEntry, twoCharEntry,
                                                                oneCharEntry.Value + twoCharEntry.Value,
                                                                oneCharEntry.RepetitionsSum + twoCharEntry.RepetitionsSum);

                charEntryNodes.Add(charEntryNode);
            }

            return(charEntryNodes.First());
        }
        private static void FormEncodingTableInternal(Dictionary <char, string> encryptingTable,
                                                      CharEntryNode charEntry, string encoding)
        {
            if (charEntry.LeftNode != null)
            {
                FormEncodingTableInternal(encryptingTable, charEntry.LeftNode, encoding + "0");
            }

            if (charEntry.RightNode != null)
            {
                FormEncodingTableInternal(encryptingTable, charEntry.RightNode, encoding + "1");
            }

            if (charEntry.LeftNode == null && charEntry.RightNode == null)
            {
                encryptingTable[Convert.ToChar(charEntry.Value)] = encoding;
            }
        }