Example #1
0
        private SKSpecialDecimal cal_node_point()
        {
            if (equation_console == "")
            {
                return(new SKSpecialDecimal());
            }
            if (NodePointStatic.compare_to(new SKSpecialDecimal(-1)) != 0)
            {
                return(NodePointStatic);
            }

            SKSpecialDecimal ret = new SKSpecialDecimal();

            //剪枝0,行数与乘数不对应
            string[] lines = spilt_string;
            if (lines[1].Length < 2 || (lines[1].Length == 2 && lines.Length != 3) || (lines[1].Length > 2 && lines[1].Length - 1 != lines.Length - 3))
            {
                ret             = new SKSpecialDecimal(-2);
                NodePointStatic = ret;
                return(ret);
            }
            //剪枝0.5:不可能的乘法-结果位数太多
            if (lines[lines.Length - 1].Length > (lines[0].Length + lines[1].Length))
            {
                ret             = new SKSpecialDecimal(-2);
                NodePointStatic = ret;
                return(ret);
            }
            //分类-按单位数乘法和多位数乘法
            if (lines[1].Length == 2)
            {
                //剪枝1:低位乘法
                if (lines[1][1] >= '0' && lines[1][1] <= '9')
                {
                    int    min_last_len = -1;
                    string lastup, lastdown;
                    lastup       = get_last_num(lines[0]);
                    lastdown     = get_last_num(lines[2]);
                    min_last_len = (lastup.Length >= lastdown.Length) ? lastdown.Length : lastup.Length;
                    if (min_last_len > 0)
                    {
                        SKSpecialDecimal mup = new SKSpecialDecimal(lines[0].Substring(lines[0].Length - min_last_len));
                        //SKSpecialDecimal mdown = new SKSpecialDecimal(lines[2].Substring(lines[2].Length - min_last_len));
                        string left = (mup * new SKSpecialDecimal(lines[1][1].ToString())).to_string_only_integer();
                        if (left.Length < min_last_len)
                        {
                            string tmpstring = "";
                            for (int i = 0; i < min_last_len - left.Length; i++)
                            {
                                tmpstring += "0";
                            }
                            left = tmpstring + left;
                        }
                        left = left.Substring(left.Length - min_last_len);
                        string right = lines[2].Substring(lines[2].Length - min_last_len);
                        if (left != right)
                        {
                            ret             = new SKSpecialDecimal(-2);
                            NodePointStatic = ret;
                            return(ret);
                        }
                    }
                }
                //剪枝2:不可能乘法(结果太大或太小)
                string[] linesa = spilt_string; //A*B最大的结果比当前C最小的数还小
                string[] linesb = spilt_string; //A*B最小的结果比当前C最大的数还大
                linesa[1] = linesa[1].Substring(1);
                linesb[1] = linesb[1].Substring(1);
                for (int j = 0; j < linesa[0].Length; j++)
                {
                    if (linesa[0][j] >= 'A' && linesa[0][j] <= 'J')
                    {
                        linesa[0] = linesa[0].Replace(linesa[0][j], '9');
                        linesb[0] = linesb[0].Replace(linesb[0][j], '0');
                    }
                }
                if (linesa[1][0] >= 'A' && linesa[1][0] <= 'J')
                {
                    linesa[1] = "9";
                    linesb[1] = "0";//TODO:这个有必要检查么?
                }
                for (int j = 0; j < linesa[2].Length; j++)
                {
                    if (linesa[2][j] >= 'A' && linesa[2][j] <= 'J')
                    {
                        linesa[2] = linesa[2].Replace(linesa[2][j], '0');
                        linesb[2] = linesb[2].Replace(linesb[2][j], '9');
                    }
                }
                SKSpecialDecimal g1 = new SKSpecialDecimal(linesa[0]);
                SKSpecialDecimal g2 = new SKSpecialDecimal(linesa[1]);
                SKSpecialDecimal g3 = new SKSpecialDecimal(linesa[2]);
                SKSpecialDecimal h1 = new SKSpecialDecimal(linesb[0]);
                SKSpecialDecimal h2 = new SKSpecialDecimal(linesb[1]);
                SKSpecialDecimal h3 = new SKSpecialDecimal(linesb[2]);
                if ((g1 * g2).compare_to(g3) < 0 || (h1 * h2).compare_to(h3) > 0)
                {
                    ret             = new SKSpecialDecimal(-2);
                    NodePointStatic = ret;
                    return(ret);
                }
                //计算分值返回
                List <int> ava = available_nums();
                if (ava.Count == 0)
                {
                    return(new SKSpecialDecimal(0));
                }
                int avg = (int)Math.Round((double)ava.Sum() / ava.Count);
                if (avg >= 10)
                {
                    avg = 9;
                }
                else if (avg <= 0)
                {
                    avg = 0;
                }
                string tmpb = equation_console;
                for (int i = 0; i < tmpb.Length; i++)
                {
                    if (tmpb[i] >= 'A' && tmpb[i] <= 'J')
                    {
                        tmpb = tmpb.Replace(tmpb[i], (char)(avg + '0'));
                    }
                }
                string[] _lines = tmpb.Split(new char[1] {
                    '_'
                });
                _lines[1] = _lines[1].Substring(1);
                SKSpecialDecimal a1 = new SKSpecialDecimal(_lines[0]);
                SKSpecialDecimal a2 = new SKSpecialDecimal(_lines[1]);
                SKSpecialDecimal a3 = new SKSpecialDecimal(_lines[2]);
                ret = SKSpecialDecimal.abs(a3 - (a1 * a2));
                ret = SKSpecialDecimal.abs(ret) + available_letters().Count;
                if (!ret.is_zero() && available_letters().Count == 0)
                {
                    ret             = new SKSpecialDecimal(-2);
                    NodePointStatic = ret;
                    return(ret);
                }
                NodePointStatic = ret;
                return(ret);
            }
            else
            {
                //多位数乘法!
                //按位执行单位数剪枝
                string up = lines[0];
                ret.reset(0);
                int lines_len = lines[1].Length - 1;//乘法中间行数
                for (int i = 1; i < lines[1].Length; i++)
                {
                    string mid = "_*" + lines[1][i];
                    //down是从下往上数第i行
                    string      down         = "_" + lines[lines.Length - i - 1];
                    string      temp_console = up + mid + down;
                    MulEquation tmp_eq       = new MulEquation(temp_console);
                    if (tmp_eq.node_point.compare_to(0) < 0)
                    {
                        ret             = new SKSpecialDecimal(-2);
                        NodePointStatic = ret;
                        return(ret);
                    }
                    ret = ret + tmp_eq.node_point;
                }
                //加法剪枝
                //目前只写一个低位剪枝先
                int      min_last_len = -1;
                string[] last         = new string[lines_len + 1];
                for (int i = 0; i < lines_len + 1; i++)
                {
                    last[i] = get_last_num(lines[i + 2]);
                    //乘法中间层补零
                    if (i < lines_len)
                    {
                        for (int j = 0; j < i; j++)
                        {
                            last[i] = last[i] + '0';
                        }
                    }
                    if (last[i].Length < min_last_len || min_last_len == -1)
                    {
                        min_last_len = last[i].Length;
                    }
                }
                if (min_last_len > 0)
                {
                    SKSpecialDecimal tmp_add  = new SKSpecialDecimal();
                    SKSpecialDecimal left_sum = new SKSpecialDecimal(0);
                    for (int i = 0; i < lines_len; i++)
                    {
                        tmp_add.reset(last[i].Substring(last[i].Length - min_last_len));
                        left_sum = left_sum + tmp_add;
                    }
                    string left = left_sum.to_string_only_integer();
                    if (left.Length < min_last_len)
                    {
                        string tmpstring = "";
                        for (int i = 0; i < min_last_len - left.Length; i++)
                        {
                            tmpstring += "0";
                        }
                        left = tmpstring + left;
                    }
                    left = left.Substring(left.Length - min_last_len);
                    string right = last[lines_len].Substring(last[lines_len].Length - min_last_len);
                    if (left != right)
                    {
                        ret             = new SKSpecialDecimal(-2);
                        NodePointStatic = ret;
                        return(ret);
                    }
                }
                //计算分值返回
                List <int> ava = available_nums();
                if (ava.Count == 0)
                {
                    return(new SKSpecialDecimal(0));
                }
                int avg = (int)Math.Round((double)ava.Sum() / ava.Count);
                if (avg >= 10)
                {
                    avg = 9;
                }
                else if (avg <= 0)
                {
                    avg = 0;
                }
                string tmpb = equation_console;
                for (int i = 0; i < tmpb.Length; i++)
                {
                    if (tmpb[i] >= 'A' && tmpb[i] <= 'J')
                    {
                        tmpb = tmpb.Replace(tmpb[i], (char)(avg + '0'));
                    }
                }
                string[] _lines = tmpb.Split(new char[1] {
                    '_'
                });
                _lines[1] = _lines[1].Substring(1);
                //只计算加法分的影响
                SKSpecialDecimal _tmp     = new SKSpecialDecimal();
                SKSpecialDecimal _tmp_sum = new SKSpecialDecimal(0);
                for (int i = 2; i < _lines.Length - 1; i++)
                {
                    _tmp.reset(_lines[i]);
                    _tmp.mul_10(i - 2);
                    _tmp_sum = _tmp_sum + _tmp;
                }
                SKSpecialDecimal _tmp_right_sum = new SKSpecialDecimal(_lines[_lines.Length - 1]);
                ret = ret + SKSpecialDecimal.abs(_tmp_right_sum - _tmp_sum);
                ret = SKSpecialDecimal.abs(ret) + available_letters().Count;
                if (!ret.is_zero() && available_letters().Count == 0)
                {
                    ret             = new SKSpecialDecimal(-2);
                    NodePointStatic = ret;
                    return(ret);
                }
                NodePointStatic = ret;
                return(ret);
            }
            return(ret);
        }
Example #2
0
        private static LinkedList <MulEquation> sorted_insert(LinkedList <MulEquation> list, List <MulEquation> calculated, MulEquation to_insert)
        {
            if (to_insert.node_point.compare_to(0) < 0)
            {
                return(list);
            }
            if (list.Count == 0)
            {
                list.AddFirst(to_insert);
                calculated.Add(to_insert);
            }
            else
            {
                for (int i = 0; i < calculated.Count; i++)
                {
                    if (to_insert.same_as(calculated[i]))
                    {
                        return(list);
                    }
                }

                LinkedListNode <MulEquation> now = list.First;
                bool inserted = false;
                for (int i = 0; i < list.Count; i++)
                {
                    if (to_insert.node_point.compare_to(now.Value.node_point) < 0)
                    {
                        list.AddBefore(now, to_insert);
                        calculated.Add(to_insert);
                        inserted = true;
                        break;
                    }
                    now = now.Next;
                }
                if (!inserted)
                {
                    list.AddLast(to_insert);
                    calculated.Add(to_insert);
                }
            }
            return(list);
        }
Example #3
0
        public async Task <string> get_results(BaseEquation equation)
        {
            string ret = "answer not found\r\n";
            LinkedList <MulEquation> sorted_equation_list     = new LinkedList <MulEquation>();
            List <MulEquation>       calculated_equation_list = new List <MulEquation>();
            MulEquation root = new MulEquation(equation);

            sorted_equation_list = sorted_insert(sorted_equation_list, calculated_equation_list, root);
            MulEquation first_ans     = null;
            bool        already_first = false;

            while (true)
            {
                if (sorted_equation_list.Count == 0)
                {
                    break;
                }
                ConsoleMazeMain.BaseEquationEventArgs ee = new ConsoleMazeMain.BaseEquationEventArgs();
                ee.be = sorted_equation_list.First.Value;
                callback(this, ee);
                bool bk = false;
                await Task.Run(() =>
                {
                    if (sorted_equation_list.First.Value.ans_found)
                    {
                        if (ret == "answer not found\r\n")
                        {
                            first_ans = sorted_equation_list.First.Value;
                            ret       = "";
                        }
                        ret += sorted_equation_list.First.Value.equation_console + "\r\n";
                        bk   = true;
                        return;
                    }
                    LinkedListNode <MulEquation> now = sorted_equation_list.First;
                    sorted_equation_list.RemoveFirst();
                    List <char> ava_l = now.Value.available_letters_from_last(1);
                    List <int> ava_n  = now.Value.available_nums();
                    for (int i = 0; i < ava_n.Count; i++)
                    {
                        if (ava_n[i] == 0)
                        {
                            int first_l = now.Value.get_first_in_each_line().IndexOf(ava_l[0]);
                            if (first_l != -1 && now.Value.spilt_string_without_operator[first_l].Length > 1)
                            {
                                continue;
                            }
                        }
                        string new_eva     = now.Value.replace(ava_l[0], ava_n[i]);
                        MulEquation new_eq = new MulEquation(new_eva);
                        if (new_eq.ans_found)
                        {
                            if (ret == "answer not found\r\n")
                            {
                                first_ans = new_eq;
                                ret       = "";
                            }
                            ret += new_eq.equation_console + "\r\n";
                            continue;
                        }
                        sorted_equation_list = sorted_insert(sorted_equation_list, calculated_equation_list, new_eq);
                    }
                });

                if (first_ans != null && !already_first)
                {
                    ConsoleMazeMain.BaseEquationEventArgs ee2 = new ConsoleMazeMain.BaseEquationEventArgs();
                    ee2.be     = first_ans;
                    ee2.is_ans = true;
                    callback(this, ee2);
                    already_first = true;
                }
                if (bk)
                {
                    break;
                }
            }
            return(ret);
        }