Solve the Equation (LeetCode)

Problem is here: https://leetcode.com/problems/solve-the-equation/#/description, or copied/pasted:

Solve a given equation and return the value of x in the form of string "x=#value". The equation contains only '+', '-' operation, the variable x and its coefficient.
If there is no solution for the equation, return "No solution".
If there are infinite solutions for the equation, return "Infinite solutions".
If there is exactly one solution for the equation, we ensure that the value of x is an integer.
Example 1:
Input: "x+5-3+x=6+x-2"
Output: "x=2"
Example 2:
Input: "x=x"
Output: "Infinite solutions"
Example 3:
Input: "2x=x"
Output: "x=0"
Example 4:
Input: "2x+3x-6x=x+2"
Output: "x=-1"
Example 5:
Input: "x=x+2"
Output: "No solution"

This is a problem of attention to details and modularization. The approach taken is to write two modules: the first one counts the "x"s given a leg of the equation. The second one counts the literals (numbers). Both are very similar, but with some diffs. They both perform tight string manipulation - it is important to be attentive to the boundaries, corner cases and the many different "states" of the string. Once you nail these two methods (and test them thoroughly in isolation), then the main method becomes rather straightforward. Code is below - cheers, Marcelo.


public class Solution
{
public string SolveEquation(string equation)
{
if (String.IsNullOrEmpty(equation)) return "No solution";

string[] parts = equation.Split('=');

int x = CountXs(parts[0]) - CountXs(parts[1]);
int literals = CountLiterals(parts[1]) - CountLiterals(parts[0]);

if (x == 0 && literals == 0)
{
return "Infinite solutions";
}
else if (x == 0)
{
return "No solution";
}
else
{
return "x=" + (literals / x).ToString();
}
}

private int CountLiterals(string equationPart)
{
if (String.IsNullOrEmpty(equationPart)) return 0;

int retVal = 0;
int signal = 1;

int partialVal = 0;
int index = 0;
while (index < equationPart.Length)
{
if (equationPart[index] == '-' || equationPart[index] == '+')
{
retVal = (signal * partialVal) + retVal;
partialVal = 0;
signal = (equationPart[index] == '-') ? -1 : 1;
}
else if (equationPart[index] >= '0' && equationPart[index] <= '9')
{
partialVal = 10 * partialVal + (int)(equationPart[index] - '0');
if (index + 1 >= equationPart.Length)
{
retVal = (signal * partialVal) + retVal;
partialVal = 0;
}
}
else if (equationPart[index] == 'x')
{
partialVal = 0;
}
index++;
}

return retVal;
}

private int CountXs(string equationPart)
{
if (String.IsNullOrEmpty(equationPart)) return 0;

int retVal = 0;
for (int i = 0; i < equationPart.Length; i++)
{
if (equationPart[i] == 'x')
{
if (i == 0) retVal++;
else
{
if (equationPart[i - 1] == '+') retVal++;
else if (equationPart[i - 1] == '-') retVal--;
else
{
int val = 0;
int index = i - 1;
int mul = 1;
while (index >= 0 && equationPart[index] >= '0' && equationPart[index] <= '9')
{
val += mul * (int)(equationPart[index] - '0');
mul *= 10;
index--;
}
if (index < 0 || equationPart[index] == '+') retVal += val;
else if (equationPart[index] == '-') retVal -= val;
}
}
}
}

return retVal;
}
}

Comments

  1. If not for you, I'd be lazy to even try this problem, since it's fairly easy in terms of algorithmic complexity, but is a good coding exercise. My lazy attempt is below:

    class Solution {
    public:
    string solveEquation(const string& equation) {
    int sign = 1;
    int x_coeff = 0;
    int val = 0;
    int last_num = -1;
    int last_op_sign = 1;
    auto get_last_num = [&](int default_value) { return last_num == -1 ? default_value : last_num; };
    for (char ch : equation) {
    switch (ch) {
    case '=':
    val += last_op_sign * sign * last_num;
    last_num = -1;
    last_op_sign = 1;
    sign = -1;
    break;
    case '+':
    case '-':
    val += last_op_sign * sign * get_last_num(0);
    last_num = -1;
    last_op_sign = ch == '-' ? -1 : 1;
    break;
    case 'x':
    x_coeff += last_op_sign * sign * get_last_num(1);
    last_num = 0;
    break;
    default:
    last_num = get_last_num(0) * 10 + (ch - '0');
    break;
    }
    }
    val += last_op_sign * sign * last_num;
    if (x_coeff == 0) return val == 0 ? "Infinite solutions" : "No solution";
    if (x_coeff < 0) {
    x_coeff *= -1;
    val *= -1;
    }
    val *= -1;
    val /= x_coeff;
    return "x=" + to_string(val);
    }
    };

    Thanks for helping me fight my natural laziness :)
    Cheers,
    Taras

    ReplyDelete

Post a Comment

Popular posts from this blog

Changing the root of a binary tree

Prompt Engineering and LeetCode

ProjectEuler Problem 719 (some hints, but no spoilers)