Ejemplo n.º 1
0
        /// <summary>
        /// Creates new SupremeComander and reades input file to commander's database.
        /// </summary>
        /// <param name="Reader">TextReader object, pointing to input file.</param>
        /// <returns>New SupremeCommander object.</returns>
        public static SupremeCommander Initialize(TextReader Reader, TextWriter Writer)
        {
            SupremeCommander thor = new SupremeCommander(Writer);

            string line         = default(string);
            int    numberOfRows = 0;

            while ((line = Reader.ReadLine()) != null)
            {
                string[] cells = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                Cell[]   row   = new Cell[cells.Length];

                for (int column = 0; column < cells.Length; column++)
                {
                    row[column] = default(Cell);
                    if (Cell.TryParse(cells[column], out row[column]))
                    {
                        continue;
                    }

                    Equation Equation = default(Equation);
                    CellType Error    = default(CellType);
                    if (Equation.TryParse(cells[column], out Equation, out Error))
                    {
                        thor.Equations.Add(new Coords(numberOfRows, column), Equation);
                        row[column] = new Cell(CellType.Equation);
                    }
                    else
                    {
                        row[column] = new Cell(Error);
                    }
                }
                thor.Data.AddRow(row);
                numberOfRows++;
            }
            return(thor);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Tries to parse data given to valid equation.
        /// </summary>
        /// <param name="EquationData">String: Data to work with.</param>
        /// <param name="Equation">Equation: Contains valid Equation or null.</param>
        /// <param name="Error">CellType: Contains Equation or errorType found during parsing.</param>
        /// <returns>On succes valid new Equation and corrsponding CellType. Empty Equation and corresponding error as CellType.</returns>
        public static bool TryParse(string EquationData, out Equation Equation, out CellType Error)
        {
            Equation = default(Equation);
            Error    = default(CellType);
            const int alphabetLength = 26;

            char[] Operators = { '=', '+', '-', '*', '/' };

            if (EquationData[0] != '=')
            {
                Error = CellType.Invalid;
                return(false);
            }
            string[] splitedData = EquationData.Split(Operators);

            if (splitedData.Length < 3)
            {
                // Missing operation
                Error = CellType.MissingOperation;
                return(false);
            }
            if (splitedData.Length > 3)
            {
                // Too many operations
                Error = CellType.Formula;
                return(false);
            }
            if (splitedData[1].Length == 0 || splitedData[2].Length == 0)
            {
                // Operator length = 0
                Error = CellType.Formula;
            }
            Coords[] Operand = new Coords[2];

            for (int i = 1; i < 3; i++)
            {
                int rowCoord    = -1;
                int columnCoord = 0;
                for (int j = 0; j < splitedData[i].Length; j++)
                {
                    if (splitedData[i][j] >= (int)'A' && splitedData[i][j] <= (int)'Z')
                    {
                        columnCoord *= alphabetLength;
                        columnCoord += (int)splitedData[i][j] - 64;
                    }
                    else if (splitedData[i][j] >= (int)'0' && splitedData[i][j] <= (int)'9')
                    {
                        if (int.TryParse(splitedData[i].Substring(j), out rowCoord))
                        {
                            Operand[i - 1] = new Coords(rowCoord - 1, columnCoord - 1);
                            break;
                        }
                        else
                        {
                            Error = CellType.Formula;
                            return(false);
                        }
                    }
                    else
                    {
                        Error = CellType.Formula;
                        return(false);
                    }
                }
                if (rowCoord < 0)
                {
                    Error = CellType.Formula;
                    return(false);
                }
            }
            Equation.FirstOperand  = Operand[0];
            Equation.SecondOperand = Operand[1];
            Equation.Operation     = (Operation)EquationData[splitedData[1].Length + 1];
            return(true);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Solves given equation and saves correct value and type to cell, holding named equation.
        /// </summary>
        /// <param name="Equation">KeyValuePair[Coords, Equation] containing coordinates to cell and equation itself.</param>
        private void SolveEquation(KeyValuePair <Coords, Equation> Equation)
        {
            Stack <KeyValuePair <Coords, Equation> > solveStack = new Stack <KeyValuePair <Coords, Equation> >();
            HashSet <Coords> locks = new HashSet <Coords>();

            solveStack.Push(Equation);

            while (solveStack.Count > 0)
            {
                KeyValuePair <Coords, Equation> peek = solveStack.Peek();
                Coords   currentKey          = peek.Key;
                Equation currentEquation     = peek.Value;
                Cell     firstOperand        = default(Cell);
                Cell     secondOperand       = default(Cell);
                Coords   firstOperandCoords  = currentEquation.FirstOperand;
                Coords   secondOperandCoords = currentEquation.SecondOperand;

                if (this.Data.AreCoordsValid(firstOperandCoords))
                {
                    firstOperand = this.Data[currentEquation.FirstOperand];
                }
                if (this.Data.AreCoordsValid(secondOperandCoords))
                {
                    secondOperand = this.Data[currentEquation.SecondOperand];
                }
                if (locks.Contains(currentKey))
                {
                    RemoveCycle(solveStack, locks, currentKey);
                    RemoveError(solveStack, locks);
                    continue;
                }
                locks.Add(currentKey);

                if (firstOperand.IsError || secondOperand.IsError)
                {
                    this.Data[currentKey] = new Cell(CellType.Error);
                    locks.Remove(currentKey);
                    return;
                }
                if (firstOperand.IsEquation)
                {
                    Coords   operandCoords   = currentEquation.FirstOperand;
                    Equation operandEquation = this.Equations[operandCoords];

                    solveStack.Push(new KeyValuePair <Coords, Equation>(operandCoords, operandEquation));
                    continue;
                }
                if (secondOperand.IsEquation)
                {
                    Coords   operandCoords   = currentEquation.SecondOperand;
                    Equation operandEquation = this.Equations[operandCoords];

                    solveStack.Push(new KeyValuePair <Coords, Equation>(operandCoords, operandEquation));
                    continue;
                }

                this.Data[currentKey] = TryCompute(firstOperand.Value, secondOperand.Value, currentEquation.Operation);
                solveStack.Pop();
                locks.Remove(currentKey);
                if (locks.Count > 0)
                {
                    locks.Remove(solveStack.Peek().Key);
                }
            }
        }