Esempio n. 1
0
        /// <summary>
        /// Performs the multiplication and prints a detailed solution.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="stepByStep">Indicates whether the operation should be performed in step-by-step mode controlled by user.</param>
        public static void Multiplication(double x, double y, bool stepByStep)
        {
            // Make the numbers whole.
            int  degree    = NumberWork.GetMostRoundingDegree(x, y);
            long xArg      = (long)(x * NumberWork.Pow(10, degree));
            long yArg      = (long)(y * NumberWork.Pow(10, degree));
            int  maxLength = NumberWork.NumLength(xArg) + NumberWork.NumLength(yArg);

            if (NumberWork.NumLength(xArg) < NumberWork.NumLength(yArg))
            {
                Swap(ref xArg, ref yArg);
            }

            // Write them.
            Console.Write(String.Join("", Enumerable.Repeat(' ', maxLength - NumberWork.NumLength(xArg))));
            Console.WriteLine($"   {xArg}");
            Console.Write(String.Join("", Enumerable.Repeat(' ', maxLength - NumberWork.NumLength(yArg))));
            Console.WriteLine($"   {yArg}");
            Console.WriteLine("   " + String.Join("", Enumerable.Repeat("-", maxLength)));

            // Get the components of the numbers.
            long[] xComps = NumberWork.GetNumberComponents(xArg);
            long[] yComps = NumberWork.GetNumberComponents(yArg);

            // Multiply each digit by each other.
            foreach (var xComp in xComps)
            {
                foreach (var yComp in yComps)
                {
                    var result    = xComp * yComp;
                    var strResult = result.ToString();

                    // Skip zeroes.
                    if (result != 0)
                    {
                        if (stepByStep)
                        {
                            Control.WaitForUserKey();
                        }

                        // Write interim result.
                        Console.Write(String.Join("", Enumerable.Repeat(' ', 3 + maxLength - strResult.Length)));
                        Console.WriteLine(strResult + $" = {xComp} * {yComp}");
                    }
                }
            }

            // Write the final result.
            Console.WriteLine("   " + String.Join("", Enumerable.Repeat("-", maxLength)));
            Console.Write(String.Join("", Enumerable.Repeat(' ', maxLength - NumberWork.NumLength(xArg * yArg))));
            Console.WriteLine($"   {xArg * yArg * Math.Pow(10, -degree * 2)}");
        }
Esempio n. 2
0
        /// <summary>
        /// Performs the subtraction and prints a detailed solution.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="stepByStep">Indicates whether the operation should be performed in step-by-step mode controlled by user.</param>
        public static void Subtraction(double x, double y, bool stepByStep)
        {
            // Make the numbers whole.
            int  degree    = NumberWork.GetMostRoundingDegree(x, y);
            long xArg      = (long)(x * NumberWork.Pow(10, degree));
            long yArg      = (long)(y * NumberWork.Pow(10, degree));
            int  maxLength = NumberWork.GetMaxLength(xArg, yArg);

            if (NumberWork.NumLength(xArg) < NumberWork.NumLength(yArg))
            {
                Swap(ref xArg, ref yArg);
            }

            Console.Write(String.Join("", Enumerable.Repeat(' ', maxLength - NumberWork.NumLength(xArg))));
            Console.WriteLine($"   {xArg}");
            Console.Write(String.Join("", Enumerable.Repeat(' ', maxLength - NumberWork.NumLength(yArg))));
            Console.WriteLine($"   {yArg}");
            Console.WriteLine("   " + String.Join("", Enumerable.Repeat("-", maxLength)));

            long[] yComps = NumberWork.GetNumberComponents(yArg);

            Console.Write(String.Join("", Enumerable.Repeat(' ', 3 + maxLength - NumberWork.NumLength(xArg))));
            Console.WriteLine(xArg);

            // Subtract each digit (component) from x and write interim results.
            foreach (var comp in yComps)
            {
                if (stepByStep)
                {
                    Control.WaitForUserKey();
                }

                Console.Write(String.Join("", Enumerable.Repeat(' ', 3 + maxLength - NumberWork.NumLength(comp))));
                Console.WriteLine(comp);
                Console.WriteLine("   " + String.Join("", Enumerable.Repeat("-", maxLength)));
                Console.Write(String.Join("", Enumerable.Repeat(' ', 3 + maxLength - NumberWork.NumLength(xArg - comp))));
                Console.WriteLine(xArg - comp);

                xArg -= comp;
            }

            Console.WriteLine("   " + String.Join("", Enumerable.Repeat("-", maxLength)));
            Console.Write(String.Join("", Enumerable.Repeat(' ', 3 + maxLength - NumberWork.NumLength(xArg) - 1)));
            Console.WriteLine(xArg * Math.Pow(10, -degree));
        }
Esempio n. 3
0
        /// <summary>
        /// Performs the addition and prints a detailed solution.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="stepByStep">Indicates whether the operation should be performed in step-by-step mode controlled by user.</param>
        public static void Addition(double x, double y, bool stepByStep)
        {
            // Make the arguments whole.
            int  degree    = NumberWork.GetMostRoundingDegree(x, y);
            long xArg      = (long)(x * NumberWork.Pow(10, degree));
            long yArg      = (long)(y * NumberWork.Pow(10, degree));
            int  maxLength = NumberWork.GetMaxLength(xArg, yArg);

            if (NumberWork.NumLength(xArg) < NumberWork.NumLength(yArg))
            {
                Swap(ref xArg, ref yArg);
            }

            Console.WriteLine($"   {xArg}");
            Console.WriteLine($"   " + String.Join("", Enumerable.Repeat(" ", maxLength - NumberWork.NumLength(yArg))) + yArg);
            Console.WriteLine("   " + String.Join("", Enumerable.Repeat("-", maxLength)));

            // Get components of the digits (see GetNumberComponents documentstion).
            long[] xComps = NumberWork.GetNumberComponents(xArg);
            long[] yComps = NumberWork.GetNumberComponents(yArg);

            for (int i = 0; i < maxLength; i++)
            {
                if (stepByStep)
                {
                    Control.WaitForUserKey();
                }

                // Add two digits (components).
                var result    = xComps[i] + (i < yComps.Length ? yComps[i] : 0);
                var strResult = result.ToString();

                // Write the result of the addition.
                Console.Write(String.Join("", Enumerable.Repeat(' ', 3 + maxLength - strResult.Length)));
                Console.WriteLine(strResult);
            }

            // Write the shrinked result.
            Console.WriteLine("   " + String.Join("", Enumerable.Repeat("-", maxLength)));
            Console.WriteLine("  " + (xArg + yArg) * Math.Pow(10, -degree));
        }
Esempio n. 4
0
        /// <summary>
        /// Computes the composite expression with a detailed solution.
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="stepByStep"></param>
        public static void ComputeExpression(string expression, bool stepByStep)
        {
            // Cast the expression to reverse polish notation and remove all meaningless spaces.
            string reversed = ReversePolishNotation.GetExpression(expression).Trim();

            // Get all the tokens delimited by spaces.
            string[] tokens = reversed.Split(' ');
            // Stack to store operands and results.
            Stack <double> stack = new Stack <double>();
            // Stage counter.
            var i = 0;

            // Traverse all tokens in the expression.
            foreach (var token in tokens)
            {
                if (token == "")
                {
                    continue;
                }

                // If token is a number, push it to the stack right away.
                if (NumberWork.IsDouble(token))
                {
                    stack.Push(double.Parse(token));

                    continue;
                }

                // If token is an operation.
                // Retrieve operaands from the stack.
                var    second = stack.Pop();
                var    first  = stack.Pop();
                double result = default;

                switch (token)
                {
                case "+":
                    Console.WriteLine($"Stage {i}: {first} + {second}");
                    Console.WriteLine();

                    Addition(first, second, stepByStep);
                    result = first + second;

                    break;

                case "-":
                    Console.WriteLine($"Stage {i}: {first} - {second}");
                    Console.WriteLine();

                    Subtraction(first, second, stepByStep);
                    result = first - second;

                    break;

                case "*":
                    Console.WriteLine($"Stage {i}: {first} * {second}");
                    Console.WriteLine();

                    Multiplication(first, second, stepByStep);
                    result = first * second;

                    break;

                case "/":
                    Console.WriteLine($"Stage {i}: {first} / {second}");
                    Console.WriteLine();

                    Division(first, second, stepByStep);
                    result = first / second;

                    break;
                }

                // Push the interim result to the stack.
                stack.Push(result);

                Console.WriteLine();

                i++;

                if (stepByStep)
                {
                    Control.WaitForUserKey();
                }
            }

            // Retrireve the final result from the stack.
            var answer = stack.Pop();

            Console.WriteLine($"Result: {answer}");
        }
Esempio n. 5
0
        /// <summary>
        /// Performs the division and prints a detailed solution.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="stepByStep">Indicates whether the operation should be performed in step-by-step mode controlled by user.</param>
        public static void Division(double x, double y, bool stepByStep)
        {
            Console.Write($"{x} / {y} = ");

            int degree = NumberWork.GetMostRoundingDegree(x, y);

            // Make the operands whole.
            long xArg = (long)(x * NumberWork.Pow(10, degree));
            long yArg = (long)(y * NumberWork.Pow(10, degree));

            Console.WriteLine($"{xArg} / {yArg}");
            Console.WriteLine();
            Console.WriteLine($"   {xArg}|{yArg}");

            // Get cursor position for the result.
            var(answerI, answerJ) = (Console.CursorLeft + 3 + NumberWork.NumLength(xArg), Console.CursorTop);
            // Get an initial value for division.
            var(div, remaining) = NumberWork.GetSufficientPartForDivision(xArg, yArg);

            Console.SetCursorPosition(answerI, answerJ);
            Console.Write("|");
            answerI++;

            var position = 3;
            // For putting a dot.
            var trigger = false;

            for (int i = 0; i < DivisionLimit; i++)
            {
                if (stepByStep)
                {
                    Control.WaitForUserKey();
                }

                // Compute the next digit of the result and write to the result position.
                var result = div / yArg;
                var(savedI, savedJ) = (Console.CursorLeft, Console.CursorTop + (i == 0 ? 0 : 1));

                Console.SetCursorPosition(answerI, answerJ);
                Console.Write(result);
                answerI++;
                Console.SetCursorPosition(savedI, savedJ);

                var rev       = result * yArg;
                var divLength = NumberWork.NumLength(div);
                var revLength = NumberWork.NumLength(rev);

                Console.SetCursorPosition(position + divLength - revLength, Console.CursorTop);
                Console.Write(rev);
                Console.SetCursorPosition(position, Console.CursorTop + 1);
                Console.Write(String.Join("", Enumerable.Repeat("-", divLength)));

                // Compute and write difference.
                div      -= rev;
                position += divLength - NumberWork.NumLength(div);

                // If it's zero, quit the loop.
                if (div == 0)
                {
                    Console.SetCursorPosition(position, Console.CursorTop + 1);
                    Console.Write(div);

                    break;
                }

                while (true)
                {
                    if (stepByStep)
                    {
                        Control.WaitForUserKey();
                    }

                    long firstDigit;

                    if (remaining == -1)
                    {
                        firstDigit = 0;

                        // If it's time to put a dot in the result.
                        if (!trigger)
                        {
                            (savedI, savedJ) = (Console.CursorLeft, Console.CursorTop);

                            Console.SetCursorPosition(answerI, answerJ);
                            Console.Write('.');
                            answerI++;
                            Console.SetCursorPosition(savedI, savedJ);

                            trigger = true;
                        }
                    }
                    else
                    {
                        (firstDigit, remaining) = NumberWork.GetFirstDigit(remaining);
                    }

                    // Add the next digit (or zero if there's no unused digits anymore).
                    div = NumberWork.Concat(div, firstDigit);

                    if (div / yArg == 0)
                    {
                        (savedI, savedJ) = (Console.CursorLeft, Console.CursorTop);

                        Console.SetCursorPosition(answerI, answerJ);
                        Console.Write(0);
                        answerI++;
                        Console.SetCursorPosition(savedI, savedJ);

                        i++;

                        if (i >= DivisionLimit)
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                Console.SetCursorPosition(position, Console.CursorTop + 1);
                Console.Write(div);
            }
        }