internal Matrix BuildMatrix(Equation eqn)
        {
            var elems  = eqn.GetElements();
            var lhs    = eqn.LeftSide;
            var rhs    = eqn.RightSide;
            var matrix = new Matrix(elems.Count + 1, lhs.Count + rhs.Count + 1);

            var i = 0;

            foreach (var elem in elems)
            {
                var j = 0;
                foreach (var term in lhs)
                {
                    matrix.Set(i, j, term.CountElement(elem));
                    j++;
                }
                foreach (var term in rhs)
                {
                    matrix.Set(i, j, -term.CountElement(elem));
                    j++;
                }
                i++;
            }
            return(matrix);
        }
        internal void CheckAnswer(Equation eqn, List <int> coefs)
        {
            if (coefs.Count != eqn.LeftSide.Count + eqn.RightSide.Count)
            {
                throw new BalancerException("Assertion error: Mismatched length");
            }

            var allzero = true;

            foreach (var coef in coefs)
            {
                allzero = allzero && coef == 0;
            }
            if (allzero)
            {
                throw new BalancerException("Assertion error: All-zero solution");
            }

            foreach (var elem in eqn.GetElements())
            {
                var sum = 0;
                var j   = 0;
                foreach (var term in eqn.LeftSide)
                {
                    sum = CheckedAdd(sum, CheckedMultiply(term.CountElement(elem), coefs[j]));
                    j++;
                }
                foreach (var term in eqn.RightSide)
                {
                    sum = CheckedAdd(sum, CheckedMultiply(term.CountElement(elem), -coefs[j]));
                    j++;
                }
                if (sum != 0)
                {
                    throw new BalancerException("Assertion error: Incorrect balance");
                }
            }
        }