/// <summary>
        /// 乘法巧算
        /// </summary>
        /// <param name="formulas">計算式作成</param>
        /// <remarks>
        /// 計算式構成樣例: 36 = (?) X 6 = (?) X 2 = 4 X (?)
        /// 結果列:6, 18, 9
        /// </remarks>
        protected virtual void CleverWithMultiple(IList <CleverCalculationFormula> formulas)
        {
            CleverCalculationFormula cleverCalculation = new CleverCalculationFormula
            {
                Type           = (int)TopicType.Multiple,
                ConfixFormulas = new List <Formula>(),
                Answer         = new List <int>()
            };

            // 乘法算式序列(取得隨機數後執行Check回調預判其是否可用)
            var list = GetMultipleSyntagmaticOrdering(formulas);

            if (!list.Any())
            {
                return;
            }

            int seq = 1;

            // 從乘法算式序列中隨機選擇3個算式(不重複)
            while (seq <= 3)
            {
                var formula = CommonUtil.GetRandomNumber(list);
                cleverCalculation.Answer.Add(formula.Gap == GapFilling.Left ? formula.LeftParameter : formula.RightParameter);
                cleverCalculation.ConfixFormulas.Add(formula);
                list.Remove(formula);

                seq++;
            }

            formulas.Add(cleverCalculation);
        }
        /// <summary>
        /// 減法巧算
        /// </summary>
        /// <param name="formulas">計算式作成</param>
        protected virtual void CleverWithSubtraction(IList <CleverCalculationFormula> formulas)
        {
            CleverCalculationFormula cleverCalculation = new CleverCalculationFormula
            {
                Type           = (int)TopicType.Plus,
                ConfixFormulas = new List <Formula>(),
                Answer         = new List <int>()
            };

            // 獲取兩個隨機非整數
            // 減數的個位是大於等於3的兩位數
            var right = CommonUtil.GetRandomNumber(20, 60, condition: _ => _ % 10 != 0 && _ % 10 >= 3, getDefault: () => 23);
            // 被減數需要滿足借位計算
            var left = CommonUtil.GetRandomNumber(50, 99, condition: _ => _ % 10 != 0 && _ > right && _ % 10 < right % 10, getDefault: () => 51);

            var answer = left - right;

            cleverCalculation.ConfixFormulas.Add(new Formula(left, right, answer, SignOfOperation.Subtraction));
            cleverCalculation.Answer.Add(answer);

            // 數字按照位數分解
            int[] lefts = new int[2] {
                left / 10, left % 10
            };
            int[] rights = new int[2] {
                right / 10, right % 10
            };
            // 距離整數的差異值
            int leftDiff  = lefts[1] >= 5 ? 10 - lefts[1] : lefts[1];
            int rightDiff = rights[1] >= 5 ? 10 - rights[1] : rights[1];

            // eg: 51 - 19 = 50 - 18 || 52 - 20
            if (lefts[1] + rights[1] == 10)
            {
                cleverCalculation.ConfixFormulas.Add(new Formula(left - leftDiff, right - leftDiff, answer, SignOfOperation.Subtraction));
                cleverCalculation.ConfixFormulas.Add(new Formula(left + rightDiff, right + rightDiff, answer, SignOfOperation.Subtraction));
            }
            // eg: 51 - 12 = 50 - 11
            else if (leftDiff < rightDiff)
            {
                cleverCalculation.ConfixFormulas.Add(new Formula(left - leftDiff, right - leftDiff, answer, SignOfOperation.Subtraction));
            }
            // eg: 53 - 19 = 54 - 20
            else if (leftDiff > rightDiff)
            {
                cleverCalculation.ConfixFormulas.Add(new Formula(left + rightDiff, right + rightDiff, answer, SignOfOperation.Subtraction));
            }

            formulas.Add(cleverCalculation);
        }
Example #3
0
        /// <summary>
        /// 加法巧算
        /// </summary>
        /// <param name="formula">計算式</param>
        /// <returns></returns>
        private string CleverWithPlus(CleverCalculationFormula formula)
        {
            StringBuilder html   = new StringBuilder();
            StringBuilder answer = new StringBuilder();

            string flag         = "topic";
            int    controlIndex = 0;

            formula.ConfixFormulas.ToList().ForEach(d =>
            {
                if ("topic".Equals(flag))
                {
                    html.AppendFormat(LABEL_HTML_FORMAT, d.LeftParameter);
                    html.AppendFormat(LABEL_HTML_FORMAT, d.Sign.ToOperationUnicode());
                    html.AppendFormat(LABEL_HTML_FORMAT, d.RightParameter);
                }
                if ("result".Equals(flag))
                {
                    html.AppendLine(string.Format(LABEL_HTML_FORMAT, SignOfCompare.Equal.ToSignOfCompareUnicode()));
                    html.AppendLine(GetHtml(GapFilling.Left, d.LeftParameter, GapFilling.Left, _parentIndex, controlIndex++));
                    html.AppendLine(string.Format(LABEL_HTML_FORMAT, d.Sign.ToOperationUnicode()));
                    html.AppendLine(GetHtml(GapFilling.Right, d.RightParameter, GapFilling.Right, _parentIndex, controlIndex++));

                    answer.AppendFormat("{0};", d.LeftParameter);
                    answer.AppendFormat("{0};", d.RightParameter);
                }
                flag = "result";
            });

            html.AppendLine(string.Format(LABEL_HTML_FORMAT, SignOfCompare.Equal.ToSignOfCompareUnicode()));
            html.AppendLine(GetHtml(GapFilling.Answer, formula.Answer[0], GapFilling.Answer, _parentIndex, controlIndex++));
            answer.AppendFormat("{0}", formula.Answer[0]);

            // 用於結果驗證
            html.AppendFormat(ANSWER_HTML_FORMAT, _parentIndex.ToString().PadLeft(2, '0'), Base64.EncodeBase64(answer.ToString()));

            return(html.ToString());
        }
Example #4
0
        /// <summary>
        /// 綜合題型巧算(拆解)
        /// </summary>
        /// <param name="formula">計算式</param>
        /// <returns></returns>
        private string CleverWithSyntheticUnknit(CleverCalculationFormula formula)
        {
            StringBuilder html   = new StringBuilder();
            StringBuilder answer = new StringBuilder();

            html.AppendFormat(LABEL_HTML_FORMAT, formula.ConfixFormulas[0].LeftParameter).AppendLine();
            html.AppendFormat(LABEL_HTML_FORMAT, formula.ConfixFormulas[0].Sign.ToOperationUnicode()).AppendLine();
            html.AppendFormat(LABEL_HTML_FORMAT, formula.ConfixFormulas[0].RightParameter).AppendLine();

            int controlIndex = 0;

            html.AppendLine(string.Format(LABEL_HTML_FORMAT, SignOfCompare.Equal.ToSignOfCompareUnicode()));
            html.AppendLine(GetHtml(GapFilling.Left, formula.ConfixFormulas[1].LeftParameter, GapFilling.Left, _parentIndex, controlIndex++));
            html.AppendLine(string.Format(LABEL_HTML_FORMAT, formula.ConfixFormulas[1].Sign.ToOperationUnicode()));
            html.AppendLine(GetHtml(GapFilling.Right, formula.ConfixFormulas[1].RightParameter, GapFilling.Right, _parentIndex, controlIndex++));

            html.AppendLine(string.Format(LABEL_HTML_FORMAT, formula.ConfixFormulas[3].Sign.ToOperationUnicode()));

            html.AppendLine(GetHtml(GapFilling.Left, formula.ConfixFormulas[2].LeftParameter, GapFilling.Left, _parentIndex, controlIndex++));
            html.AppendLine(string.Format(LABEL_HTML_FORMAT, formula.ConfixFormulas[2].Sign.ToOperationUnicode()));
            html.AppendLine(GetHtml(GapFilling.Right, formula.ConfixFormulas[2].RightParameter, GapFilling.Right, _parentIndex, controlIndex++));

            html.AppendLine(string.Format(LABEL_HTML_FORMAT, SignOfCompare.Equal.ToSignOfCompareUnicode()));

            html.AppendLine(GetHtml(GapFilling.Answer, formula.Answer[0], GapFilling.Answer, _parentIndex, controlIndex++));

            answer.AppendFormat("{0};", formula.ConfixFormulas[1].LeftParameter);
            answer.AppendFormat("{0};", formula.ConfixFormulas[1].RightParameter);
            answer.AppendFormat("{0};", formula.ConfixFormulas[2].LeftParameter);
            answer.AppendFormat("{0};", formula.ConfixFormulas[2].RightParameter);
            answer.AppendFormat("{0}", formula.Answer[0]);

            // 用於結果驗證
            html.AppendFormat(ANSWER_HTML_FORMAT, _parentIndex.ToString().PadLeft(2, '0'), Base64.EncodeBase64(answer.ToString()));

            return(html.ToString());
        }
Example #5
0
        /// <summary>
        /// 乘法巧算
        /// </summary>
        /// <param name="formula">計算式</param>
        /// <returns></returns>
        private string CleverWithMultiple(CleverCalculationFormula formula)
        {
            StringBuilder html   = new StringBuilder();
            StringBuilder answer = new StringBuilder();

            html.AppendFormat(LABEL_HTML_FORMAT, formula.ConfixFormulas[0].Answer);

            int controlIndex = 0;

            formula.ConfixFormulas.ToList().ForEach(d =>
            {
                html.AppendLine(string.Format(LABEL_HTML_FORMAT, SignOfCompare.Equal.ToSignOfCompareUnicode()));
                html.AppendLine(GetHtml(d.Gap, d.LeftParameter, GapFilling.Left, _parentIndex, controlIndex++));
                html.AppendLine(string.Format(LABEL_HTML_FORMAT, SignOfOperation.Multiple.ToOperationUnicode()));
                html.AppendLine(GetHtml(d.Gap, d.RightParameter, GapFilling.Right, _parentIndex, controlIndex++));
            });

            formula.Answer.ForEach(d => answer.AppendFormat("{0};", d));
            answer.Length -= 1;
            // 用於結果驗證
            html.AppendFormat(ANSWER_HTML_FORMAT, _parentIndex.ToString().PadLeft(2, '0'), Base64.EncodeBase64(answer.ToString()));

            return(html.ToString());
        }
Example #6
0
 /// <summary>
 /// 減法巧算
 /// </summary>
 /// <param name="formula">計算式</param>
 /// <returns></returns>
 private string CleverWithSubtraction(CleverCalculationFormula formula)
 {
     return(CleverWithPlus(formula));
 }
        /// <summary>
        /// 綜合題型巧算(合併)
        /// </summary>
        /// <param name="formulas">計算式作成</param>
        protected virtual void CleverWithSyntheticCombine(IList <CleverCalculationFormula> formulas)
        {
            // 當前反推判定次數(一次推算內次數累加)
            int defeated = 0;

            CleverCalculationFormula cleverCalculation = new CleverCalculationFormula
            {
                Type           = (int)Synthetic.Combine,
                ConfixFormulas = new List <Formula>(),
                Answer         = new List <int>()
            };

            while (1 == 1)
            {
                // 如果大於三次則認為此題無法作成繼續下一題
                if (defeated == INVERSE_NUMBER)
                {
                    cleverCalculation = null;
                    break;
                }

                cleverCalculation.ConfixFormulas.Clear();
                cleverCalculation.Answer.Clear();

                var answer = 0;
                // 獲取一個10以內的共有因數
                int factorShare = CommonUtil.GetRandomNumber(3, 9);

                // 合併方法(加法或者减法)
                SignOfOperation combine = CommonUtil.GetRandomNumber(SignOfOperation.Plus, SignOfOperation.Subtraction);

                StringBuilder express = new StringBuilder();
                // 加法合併
                if (combine == SignOfOperation.Plus)
                {
                    int factor1 = CommonUtil.GetRandomNumber(1, 9);

                    // 加法合併的兩種情況:
                    // 1.相加之和是整十數
                    int factor2 = CommonUtil.GetRandomNumber(1, 50, condition: _ => (_ % 10 == 0 || _ + factor1 <= 10) && _ != factor1, getDefault: () => 30);
                    // 2.相加之和是十
                    if (factor2 > 10)
                    {
                        factor2 -= factor1;
                    }
                    // 隨機排列計算式各參數(打亂參數位置)
                    SetNewGuidFactors(out List <int> factors1, factorShare, factor1);
                    SetNewGuidFactors(out List <int> factors2, factorShare, factor2);
                    // eg: 8 * 5 + 2 * 5 = (8 + 2) * 5 = 10 * 5
                    express.AppendFormat(CultureInfo.CurrentCulture, "{0}*{1}+{2}*{3}", factors1[0], factors1[1], factors2[0], factors2[1]);

                    answer = (factor1 + factor2) * factorShare;
                    cleverCalculation.ConfixFormulas.Add(new Formula(factor1 + factor2, factorShare, answer, SignOfOperation.Multiple));
                    cleverCalculation.Answer.Add(answer);
                }
                // 減法合併
                else
                {
                    int factor1 = CommonUtil.GetRandomNumber(11, 19);
                    int factor2 = CommonUtil.GetRandomNumber(5, 9, condition: _ => factor1 - _ <= 10, getDefault: () => 5);

                    // 隨機排列計算式各參數(打亂參數位置)
                    SetNewGuidFactors(out List <int> factors1, factorShare, factor1);
                    SetNewGuidFactors(out List <int> factors2, factorShare, factor2);
                    // eg: 18 * 5 - 9 * 5 = (18 - 9) * 5 = 20
                    express.AppendFormat(CultureInfo.CurrentCulture, "{0}*{1}-{2}*{3}", factors1[0], factors1[1], factors2[0], factors2[1]);

                    answer = (factor1 - factor2) * factorShare;
                    cleverCalculation.ConfixFormulas.Add(new Formula(factor1 - factor2, factorShare, answer, SignOfOperation.Multiple));
                    cleverCalculation.Answer.Add(answer);
                }

                // 計算式推導
                var calc = new ExpressArithmeticUtil();
                if (!calc.IsResult(express.ToString(), out int result))
                {
                    defeated++;
                    continue;
                }
                if (result != answer)
                {
                    defeated++;
                    continue;
                }
                // 加入推導出計算式集合
                calc.Formulas.ToList().ForEach(f => cleverCalculation.ConfixFormulas.Add(f));
                defeated = 0;

                break;
            }

            if (cleverCalculation != null)
            {
                formulas.Add(cleverCalculation);
            }
        }
        /// <summary>
        /// 綜合題型巧算(拆解)
        /// </summary>
        /// <param name="formulas">計算式作成</param>
        protected virtual void CleverWithSyntheticUnknit(IList <CleverCalculationFormula> formulas)
        {
            // 當前反推判定次數(一次推算內次數累加)
            int defeated = 0;

            CleverCalculationFormula cleverCalculation = new CleverCalculationFormula
            {
                Type           = (int)Synthetic.Unknit,
                ConfixFormulas = new List <Formula>(),
                Answer         = new List <int>()
            };

            while (1 == 1)
            {
                // 如果大於三次則認為此題無法作成繼續下一題
                if (defeated == INVERSE_NUMBER)
                {
                    cleverCalculation = null;
                    break;
                }

                cleverCalculation.ConfixFormulas.Clear();
                cleverCalculation.Answer.Clear();

                // 獲取一個待拆解的非整數(不包含各位為5的數)
                int unknitValue = CommonUtil.GetRandomNumber(10, 60, condition: _ => _ % 10 != 0 && _ % 10 != 5, getDefault: () => 46);
                // 獲取一個10以內的因數
                int factor = CommonUtil.GetRandomNumber(3, 9, condition: _ => _ != unknitValue % 10, getDefault: () => 5);

                // 數字按照位數分解
                int[] unknits = new int[2] {
                    unknitValue / 10, unknitValue % 10
                };
                // 距離整數的差異值
                int unknitDiff = unknits[1] >= 5 ? 10 - unknits[1] : unknits[1];

                // 結果值
                int answer = unknitValue * factor;
                // 用於設定待拆解因數的位置
                LeftOrRight leftOrRight = CommonUtil.GetRandomNumber(LeftOrRight.Left, LeftOrRight.Right);
                cleverCalculation.Answer.Add(answer);
                if (leftOrRight == LeftOrRight.Left)
                {
                    cleverCalculation.ConfixFormulas.Add(new Formula(unknitValue, factor, answer, SignOfOperation.Multiple));
                }
                else
                {
                    cleverCalculation.ConfixFormulas.Add(new Formula(factor, unknitValue, answer, SignOfOperation.Multiple));
                }

                StringBuilder express = new StringBuilder();
                // 加法拆解
                if (unknits[1] < 5)
                {
                    // eg: 12 * 5 = 10 * 5 + 2 * 5
                    express.AppendFormat(CultureInfo.CurrentCulture, "{0}*{1}+{2}*{3}", unknitValue - unknitDiff, factor, unknits[1], factor);
                }
                // 減法拆解
                else
                {
                    // eg: 18 * 5 = 20 * 5 - 2 * 5
                    express.AppendFormat(CultureInfo.CurrentCulture, "{0}*{1}-{2}*{3}", unknitValue + unknitDiff, factor, unknitDiff, factor);
                }

                // 計算式推導
                var calc = new ExpressArithmeticUtil();
                if (!calc.IsResult(express.ToString(), out int result))
                {
                    defeated++;
                    continue;
                }
                if (result != answer)
                {
                    defeated++;
                    continue;
                }
                // 加入推導出計算式集合
                calc.Formulas.ToList().ForEach(f => cleverCalculation.ConfixFormulas.Add(f));
                defeated = 0;

                break;
            }

            if (cleverCalculation != null)
            {
                formulas.Add(cleverCalculation);
            }
        }
        /// <summary>
        /// 加法巧算
        /// </summary>
        /// <param name="formulas">計算式作成</param>
        /// <remarks>
        /// 計算式構成樣例: 57 + 78 = (?) + (?) = (?)
        /// 結果列:135
        /// </remarks>
        protected virtual void CleverWithPlus(IList <CleverCalculationFormula> formulas)
        {
            CleverCalculationFormula cleverCalculation = new CleverCalculationFormula
            {
                Type           = (int)TopicType.Plus,
                ConfixFormulas = new List <Formula>(),
                Answer         = new List <int>()
            };

            // 獲取兩個隨機非整數
            var left   = CommonUtil.GetRandomNumber(10, 99, _ => _ % 10 != 0, () => 11);
            var right  = CommonUtil.GetRandomNumber(10, 99, _ => _ % 10 != 0 && _ != left, () => 12);
            var answer = left + right;

            cleverCalculation.ConfixFormulas.Add(new Formula(left, right, answer, SignOfOperation.Plus));
            cleverCalculation.Answer.Add(answer);

            // 數字按照位數分解
            int[] lefts = new int[2] {
                left / 10, left % 10
            };
            int[] rights = new int[2] {
                right / 10, right % 10
            };
            // 距離整數的差異值
            int leftDiff  = lefts[1] >= 5 ? 10 - lefts[1] : lefts[1];
            int rightDiff = rights[1] >= 5 ? 10 - rights[1] : rights[1];

            // eg: 58 + 57 => 60 + 59
            // eg: 58 + 12 => 60 + 10
            // eg: 55 + 25 => 60 + 20 || 50 + 30
            if (lefts[1] >= 5 && (leftDiff < rightDiff || lefts[1] + rights[1] == 10))
            {
                // 左邊的值向上化整
                cleverCalculation.ConfixFormulas.Add(new Formula(left + leftDiff, right - leftDiff, answer, SignOfOperation.Plus));
                // 左右兩邊的值向上化整
                if (lefts[1] == 5 && rights[1] == 5)
                {
                    cleverCalculation.ConfixFormulas.Add(new Formula(left - leftDiff, right + leftDiff, answer, SignOfOperation.Plus));
                }
            }
            // eg: 58 + 48 => 60 + 46 || 56 + 50
            else if (lefts[1] > 5 && lefts[1] == rights[1])
            {
                // 左右兩邊的值向上化整
                cleverCalculation.ConfixFormulas.Add(new Formula(left + leftDiff, right - leftDiff, answer, SignOfOperation.Plus));
                cleverCalculation.ConfixFormulas.Add(new Formula(left - rightDiff, right + rightDiff, answer, SignOfOperation.Plus));
            }
            // eg: 57 + 69 => 56 + 70
            // eg: 57 + 61 => 58 + 60
            // eg: 55 + 21 => 56 + 20
            // eg: 55 + 28 => 57 + 30
            else if (lefts[1] >= 5 && leftDiff > rightDiff)
            {
                if (rights[1] >= 5)
                {
                    // 右邊的值向上化整
                    cleverCalculation.ConfixFormulas.Add(new Formula(left - rightDiff, right + rightDiff, answer, SignOfOperation.Plus));
                }
                else
                {
                    // 右邊的值向下化整
                    cleverCalculation.ConfixFormulas.Add(new Formula(left + rightDiff, right - rightDiff, answer, SignOfOperation.Plus));
                }
            }
            // eg: 51 + 52 => 50 + 53
            // eg: 51 + 59 => 50 + 60
            // eg: 55 + 59 => 54 + 60
            else if (lefts[1] <= 5 && (leftDiff < rightDiff || lefts[1] + rights[1] == 10))
            {
                // 左邊的值向下化整
                cleverCalculation.ConfixFormulas.Add(new Formula(left - lefts[1], right + lefts[1], answer, SignOfOperation.Plus));
            }
            // eg: 51 + 41 => 50 + 42 || 52 + 40
            else if (lefts[1] < 5 && lefts[1] == rights[1])
            {
                // 左右兩邊的值向下化整
                cleverCalculation.ConfixFormulas.Add(new Formula(left - lefts[1], right + lefts[1], answer, SignOfOperation.Plus));
                cleverCalculation.ConfixFormulas.Add(new Formula(left + lefts[1], right - rights[1], answer, SignOfOperation.Plus));
            }
            // eg: 54 + 61 => 55 + 60
            // eg: 54 + 69 => 53 + 70
            // eg: 55 + 33 => 58 + 30
            else if (lefts[1] <= 5 && leftDiff > rightDiff)
            {
                if (rights[1] >= 5)
                {
                    // 右邊的值向上化整
                    cleverCalculation.ConfixFormulas.Add(new Formula(left - rightDiff, right + rightDiff, answer, SignOfOperation.Plus));
                }
                else
                {
                    // 右邊的值向下化整
                    cleverCalculation.ConfixFormulas.Add(new Formula(left + rights[1], right - rights[1], answer, SignOfOperation.Plus));
                }
            }
            // eg: 55 + 25 => 50 + 30 || 60 + 20
            else if (lefts[1] == 5 && rights[1] == 5)
            {
                // 左右兩邊的值均可向下或者向下化整
                cleverCalculation.ConfixFormulas.Add(new Formula(left - 5, right + 5, answer, SignOfOperation.Plus));
                cleverCalculation.ConfixFormulas.Add(new Formula(left + 5, right - 5, answer, SignOfOperation.Plus));
            }

            formulas.Add(cleverCalculation);
        }