public static string mergeAll(string exp, evalResult result)
        {
            exp = mergeNegations(exp, result);

            exp = mergeMult(exp, result);
            exp = mergeAdd(exp, result);
            exp = mergeBrackets(exp, result);

            return(exp);
        }
        public static string mergeNegations(string exp, evalResult result)
        {
            if (exp.Contains("~0") || exp.Contains("~1"))
            {
                exp = exp.Replace("~0", "1");
                exp = exp.Replace("~1", "0");
                result.addStrStep(exp);
            }

            return(exp);
        }
        public static string mergeBrackets(string exp, evalResult result)
        {
            if (exp.Contains("(0)") || exp.Contains("(1)"))
            {
                exp = exp.Replace("(0)", "0");
                exp = exp.Replace("(1)", "1");
                result.addStrStep(exp);
            }

            return(exp);
        }
        public static string mergeAdd(string exp, evalResult result)
        {
            if (exp.Contains("+"))
            {
                exp = ReplaceFirst(exp, "0+1", "1");
                exp = ReplaceFirst(exp, "1+1", "1");
                exp = ReplaceFirst(exp, "1+0", "1");
                exp = ReplaceFirst(exp, "0+0", "0");
                result.addStrStep(exp);
            }

            return(exp);
        }
        public static evalResult evaluateValue(string exp, inputObj[] inputs)
        {
            string s_exp        = exp;
            var    elements_tmp = Regex.Matches(exp, "~[a-z0-1]|[a-z0-1]");
            var    elements     = new List <string>();
            var    result       = new evalResult();

            foreach (var el in elements_tmp)
            {
                elements.Add(el.ToString());
            }
            for (int i = 0; i < elements.Count; i++)
            {
                for (int i2 = 0; i2 < inputs.Length; i2++)
                {
                    elements[i] = elements[i].Replace(inputs[i2].letter + "", inputs[i2].state.ToString());
                    s_exp       = s_exp.Replace(inputs[i2].letter + "", inputs[i2].state.ToString());
                }
                var regex   = new Regex("[a-z]");
                var newText = regex.Replace(elements[i], "0");
                elements[i] = newText;
                newText     = regex.Replace(s_exp, "0");
                s_exp       = newText;
            }
            if (s_exp.Length < 1)
            {
                s_exp = "0";
            }
            var prev_s_exp = "";

            result.addStrStep(s_exp);
            while (s_exp.Contains("+") || s_exp.Contains("*") || s_exp.Contains("~"))
            {
                if (s_exp.Length == 1)
                {
                    return(result);
                }
                s_exp = boolUtils.mergeAll(s_exp, result);
                if (prev_s_exp == s_exp)
                {
                    result.addStrStep("ERROR");
                    return(result);
                }
                prev_s_exp = s_exp;
            }

            return(result);
        }
        public static string mergeMult(string exp, evalResult result)
        {
            while (exp.Contains("00") || exp.Contains("01") || exp.Contains("10") || exp.Contains("11"))
            {
                exp = ReplaceFirst(exp, "00", "0*0");
                exp = ReplaceFirst(exp, "11", "1*1");
                exp = ReplaceFirst(exp, "10", "1*0");
                exp = ReplaceFirst(exp, "01", "0*1");

                result.addStrStep(exp);
            }
            if (exp.Contains("*"))
            {
                exp = ReplaceFirst(exp, "0*1", "0");
                exp = ReplaceFirst(exp, "1*1", "1");
                exp = ReplaceFirst(exp, "1*0", "0");
                exp = ReplaceFirst(exp, "0*0", "0");
                result.addStrStep(exp);
            }

            return(exp);
        }
        public static evalResult isFunctionsEqualsHard(string exp1, string exp2)
        {
            var result = new evalResult();
            var vars1  = new List <char>();
            var vars2  = new List <char>();

            foreach (var item in exp1.ToCharArray())
            {
                if (Regex.IsMatch(item.ToString(), "[a-w]"))
                {
                    if (!vars1.Contains(item))
                    {
                        vars1.Add(item);
                    }
                }
            }
            foreach (var item in exp2.ToCharArray())
            {
                if (Regex.IsMatch(item.ToString(), "[a-w]"))
                {
                    if (!vars2.Contains(item))
                    {
                        vars2.Add(item);
                    }
                }
            }

            int max1 = Convert.ToInt32(Math.Pow((double)2, (double)vars1.Count));
            int max2 = Convert.ToInt32(Math.Pow((double)2, (double)vars2.Count));

            var results1 = new List <string>();
            var results2 = new List <string>();

            for (int i = 0; i < max1; i++)
            {
                string binary = Convert.ToString(i, 2);
                while (binary.Length < vars1.Count)
                {
                    binary = "0" + binary;
                }

                var inputs = new List <inputObj>();

                for (int i2 = 0; i2 < vars1.Count; i2++)
                {
                    inputs.Add(new inputObj(binary[i2] == '0' ? 0 : 1, vars1[i2]));
                }

                var res = evaluateValue(exp1, inputs.ToArray());
                results1.Add(res.result_str());
                var res2 = evaluateValue(exp2, inputs.ToArray());
                results2.Add(res2.result_str());

                result.addStrStep($"X: {binary} > {res.result_str()}    Y: {binary} > {res2.result_str()}       > {(res.result_str()==res2.result_str()?"1":"0")}");
            }

            for (int i = 0; i < max2; i++)
            {
                string binary = Convert.ToString(i, 2);
                while (binary.Length < vars2.Count)
                {
                    binary = "0" + binary;
                }

                var inputs = new List <inputObj>();

                for (int i2 = 0; i2 < vars2.Count; i2++)
                {
                    inputs.Add(new inputObj(binary[i2] == '0' ? 0 : 1, vars2[i2]));
                }
                var res = evaluateValue(exp1, inputs.ToArray());
                results1.Add(res.result_str());
                var res2 = evaluateValue(exp2, inputs.ToArray());
                results2.Add(res2.result_str());

                result.addStrStep($"X: {binary} > {res.result_str()}    Y: {binary} > {res2.result_str()}       > {(res.result_str() == res2.result_str() ? "1" : "0")}");
            }
            result.addStrStep("\n");

            var equals = true;

            for (int i = 0; i < results1.Count; i++)
            {
                result.addStrStep($"{results1[i]}*{results1[i]} = {(results1[i] != results2[i] ? "0" : "1")}");
                if (results1[i] != results2[i])
                {
                    equals = false;
                }
            }
            result.addStrStep("\n");
            result.addStrStep($"{(equals?"1":"0")}");
            return(result);
        }