Enter an expression or equation to simplify or solve for x
class plusNode extends Node {
constructor(left, right) {
super();
this.left = left;
this.right = right;
}
toString() {
const rightStr = this.right.toString();
if (rightStr.startsWith("-")) {
return \${this.left.toString()} - \${rightStr.slice(1)};
}
return (\${this.left.toString()} + \${rightStr});
}
simplify() {
const left = this.left.simplify();
const right = this.right.simplify();
const terms = collectTerms(this);
const xCoef = terms.x || 0;
const constant = terms.constant || 0;
if (xCoef === 0 && constant === 0) return new NumberNode(0);
if (xCoef === 0) return new NumberNode(constant);
if (constant === 0)
return new multiplyNode(new NumberNode(xCoef), new SymbolNode("x"));
const xTerm = new multiplyNode(new NumberNode(xCoef), new SymbolNode("x"));
return new plusNode(xTerm, new NumberNode(constant));
}
}
function tokenize(str) {
const operators = ["+", "-", "*", "="];
const tokens = [];
let current = "";
for (let i = 0; i < str.length; i++) {
if (operators.includes(str[i])) {
if (current) {
tokens.push(current);
current = "";
}
if (
str[i] === "-" &&
(i === 0 || operators.includes(str[i - 1])) &&
i + 1 < str.length &&
/\d/.test(str[i + 1])
) {
current = "-";
} else {
tokens.push(str[i]);
}
} else {
current += str[i];
}
}
if (current) tokens.push(current);
return tokens.filter((t) => t !== "");
}
function parseTerm(tokens, start) {
if (start >= tokens.length) throw new Error("Invalid term: no tokens left");
if (start + 2 < tokens.length && tokens[start + 1] === "*") {
const coef = new NumberNode(parseFloat(tokens[start]));
const varX = new SymbolNode(tokens[start + 2]);
const node = new multiplyNode(coef, varX);
node.tokensConsumed = 3;
return node;
} else {
const value = parseFloat(tokens[start]);
const node = isNaN(value) ? new SymbolNode(tokens[start]) : new NumberNode(value);
node.tokensConsumed = 1;
return node;
}
}