public void ChainEfficiency()
        {
            var dict = HuffmanTreeTests.NumberCharacterGenerator(200);
            var w    = HuffmanTreeTests.GenerateString(dict);

            HuffmanChain chain;
            HuffmanTree  tree;
            string       cW, cT;

            var condenser = new SingleCondenser();

            (cW, chain) = condenser.Condense(w);
            (cT, tree)  = condenser.CondenseToTree(w);

            Assert.NotNull(chain);
            Assert.NotNull(tree);

            Assert.LessOrEqual(cW.Length, cT.Length);
            Assert.LessOrEqual((double)cW.Length / cT.Length, .95);


            TestContext.WriteLine(
                $"Chain vs Tree Efficiency: cW/cT = {(double) cW.Length / cT.Length:P} size decrease");
            TestContext.WriteLine($"Chain Overall Efficiency: cW/w = {(double) cW.Length / w.Length:P} size decrease");
            TestContext.WriteLine($"Tree Overall Efficiency: cW/w = {(double) cT.Length / w.Length:P} size decrease");
            TestContext.WriteLine();
        }
        public void TestCondenser(int maxChars, int minChars = 0, char minChar = ' ', char maxChar = '~')
        {
            var dict  = HuffmanTreeTests.NumberCharacterGenerator(minChars, maxChars, minChar, maxChar);
            var w     = HuffmanTreeTests.GenerateString(dict);
            var total = HuffmanTreeTests.Total(dict);

            var          condenser      = new SingleCondenser();
            var          condenseOutput = "";
            HuffmanChain chain          = null;

            Assert.DoesNotThrow(() => {
                (string w, HuffmanChain c)valueTuple = condenser.Condense(w);
                condenseOutput = valueTuple.w;
                chain          = valueTuple.c;
            });


            Assert.LessOrEqual(condenseOutput.Length, w.Length);

            Assert.NotNull(chain);

            var expander = new SingleExpander();
            var expanded = expander.Expand(condenseOutput, chain, total);


            Assert.AreEqual(w, expanded);

            TestContext.WriteLine(
                $"Chain Overall Efficiency: cW/w = {(double) condenseOutput.Length / w.Length:P} size decrease");
            TestContext.WriteLine();
        }
        public void ChainStringService(int maxChars, int minChars = 0, char minChar = ' ', char maxChar = '~')
        {
            var dict = HuffmanTreeTests.NumberCharacterGenerator(minChars, maxChars, minChar, maxChar);
            var w    = HuffmanTreeTests.GenerateString(dict);

            HuffmanChain chain;
            var          condenser = new SingleCondenser();

            chain = condenser.Condense(w).Item2;

            var output = new HuffmanChain.HuffmanChainOutputService().CreateOutput(chain);

            TestContext.WriteLine(output);
        }
        public void ChainReproductability(int maxChars, int minChars = 0, char minChar = ' ', char maxChar = '~')
        {
            var dict  = HuffmanTreeTests.NumberCharacterGenerator(minChars, maxChars, minChar, maxChar);
            var w     = HuffmanTreeTests.GenerateString(dict);
            var chain = new HuffmanChain(w);


            var output = chain.ToString();

            TestContext.WriteLine("Original: " + output);
            var recreated = HuffmanChain.Reconstruct(output);

            var recreatedString = chain.ToString();

            TestContext.WriteLine("Recreated: " + recreatedString);

            Assert.AreEqual(output, recreatedString);
            Assert.IsTrue(chain.Equals(recreated));
        }