I'm new to JavaScript and I am trying to write a simple script that solves linear equations. So far my script solves linear equations that are plus and minus only such as "2x + 28 - 18x = 36 - 4x + 10". I want it to also be able to solve linear equations/algebra problems that contain multiplication and division such as "2x * 3x = 4 / 2x".
I kind of have an idea of what to do next but I think the script I have right now maybe overly plex and it's only going to make it more plicated to add the multiplication and division.
Below is my script. I'm hoping for a few pointers on how I could improve and simplify what I already have and what the best way to add multiplication and division?
My script on JS Bin:
My script:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ".dtd">
<html xmlns="">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Problem Solver</title>
<script>
window.onload = function() {
// Total Xs on each side of equation
// Example problem: 5x + 2 = 10 - 2x
var leftSideXTotal = 0; // 5
var rightSideXTotal = 0; // -2
// Total integers on each side of equation
// Example problem: 5x + 2 = 10 - 2x
var leftSideIntTotal = 0; // 2
var rightSideIntTotal = 0; // 10
// Enter a math problem to solve
var problem = "5x + 2 = 10 - 2x";
// Remove all spaces in problem
// Example problem: 5x + 2 = 10 - 2x
problem = problem.replace(/\s/g,''); // 5x+2=10-2x
// Add + signs in front of all - signs
// Example problem: 5x + 2 = 10 - 2x
problem = problem.replace(/-/gi, "+-"); // 5x+2=10+-2x
// Split problem into left and right sides
// Example problem: 5x + 2 = 10 - 2x
var problemArray = problem.split("=");
var problemLeftSide = problemArray[0]; // 5x+2
var problemRightSide = problemArray[1]; // 10+-2x
// Split values on each side into an array
var problemLeftSideValues = problemLeftSide.split("+");
var problemRightSideValues = problemRightSide.split("+");
// Go through the left side values and add them up
for (var i = 0; i < problemLeftSideValues.length; i++) {
// Current value
var currentValue = problemLeftSideValues[i];
// Length of current value
var currentValueLength = currentValue.length;
if (currentValue.charAt(currentValueLength - 1) == "x") { //Check if current value is a X value
// Remove X from end of current value
currentValue = currentValue.split("x");
// Add to total Xs on left side
leftSideXTotal = Number(leftSideXTotal) + Number(currentValue[0]);
} else {
// Add to total integers on left side
leftSideIntTotal = Number(leftSideIntTotal) + Number(problemLeftSideValues[i]);
}
}
// Go through the right side values and add them up
for (var i = 0; i < problemRightSideValues.length; i++) {
// Current value
var currentValue = problemRightSideValues[i];
// Length of current value
var currentValueLength = currentValue.length;
if (currentValue.charAt(currentValueLength - 1) == "x") { //Check if current value is a X value
// Remove X from end of current value
currentValue = currentValue.split("x");
// Add to total Xs on right side
rightSideXTotal = Number(rightSideXTotal) + Number(currentValue[0]);
} else {
// Add to total integers on right side
rightSideIntTotal = Number(rightSideIntTotal) + Number(problemRightSideValues[i]);
}
}
// Compute
var totalXs = (leftSideXTotal - rightSideXTotal)
var totalIntegers = (rightSideIntTotal - leftSideIntTotal)
var solution = (totalIntegers / totalXs)
// Display solution
document.getElementById("divSolution").innerText = solution;
}
</script>
</head>
<body>
<div id="divSolution"></div>
</body>
</html>
I'm new to JavaScript and I am trying to write a simple script that solves linear equations. So far my script solves linear equations that are plus and minus only such as "2x + 28 - 18x = 36 - 4x + 10". I want it to also be able to solve linear equations/algebra problems that contain multiplication and division such as "2x * 3x = 4 / 2x".
I kind of have an idea of what to do next but I think the script I have right now maybe overly plex and it's only going to make it more plicated to add the multiplication and division.
Below is my script. I'm hoping for a few pointers on how I could improve and simplify what I already have and what the best way to add multiplication and division?
My script on JS Bin: http://jsbin./ufekug/1/edit
My script:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Problem Solver</title>
<script>
window.onload = function() {
// Total Xs on each side of equation
// Example problem: 5x + 2 = 10 - 2x
var leftSideXTotal = 0; // 5
var rightSideXTotal = 0; // -2
// Total integers on each side of equation
// Example problem: 5x + 2 = 10 - 2x
var leftSideIntTotal = 0; // 2
var rightSideIntTotal = 0; // 10
// Enter a math problem to solve
var problem = "5x + 2 = 10 - 2x";
// Remove all spaces in problem
// Example problem: 5x + 2 = 10 - 2x
problem = problem.replace(/\s/g,''); // 5x+2=10-2x
// Add + signs in front of all - signs
// Example problem: 5x + 2 = 10 - 2x
problem = problem.replace(/-/gi, "+-"); // 5x+2=10+-2x
// Split problem into left and right sides
// Example problem: 5x + 2 = 10 - 2x
var problemArray = problem.split("=");
var problemLeftSide = problemArray[0]; // 5x+2
var problemRightSide = problemArray[1]; // 10+-2x
// Split values on each side into an array
var problemLeftSideValues = problemLeftSide.split("+");
var problemRightSideValues = problemRightSide.split("+");
// Go through the left side values and add them up
for (var i = 0; i < problemLeftSideValues.length; i++) {
// Current value
var currentValue = problemLeftSideValues[i];
// Length of current value
var currentValueLength = currentValue.length;
if (currentValue.charAt(currentValueLength - 1) == "x") { //Check if current value is a X value
// Remove X from end of current value
currentValue = currentValue.split("x");
// Add to total Xs on left side
leftSideXTotal = Number(leftSideXTotal) + Number(currentValue[0]);
} else {
// Add to total integers on left side
leftSideIntTotal = Number(leftSideIntTotal) + Number(problemLeftSideValues[i]);
}
}
// Go through the right side values and add them up
for (var i = 0; i < problemRightSideValues.length; i++) {
// Current value
var currentValue = problemRightSideValues[i];
// Length of current value
var currentValueLength = currentValue.length;
if (currentValue.charAt(currentValueLength - 1) == "x") { //Check if current value is a X value
// Remove X from end of current value
currentValue = currentValue.split("x");
// Add to total Xs on right side
rightSideXTotal = Number(rightSideXTotal) + Number(currentValue[0]);
} else {
// Add to total integers on right side
rightSideIntTotal = Number(rightSideIntTotal) + Number(problemRightSideValues[i]);
}
}
// Compute
var totalXs = (leftSideXTotal - rightSideXTotal)
var totalIntegers = (rightSideIntTotal - leftSideIntTotal)
var solution = (totalIntegers / totalXs)
// Display solution
document.getElementById("divSolution").innerText = solution;
}
</script>
</head>
<body>
<div id="divSolution"></div>
</body>
</html>
Share
Improve this question
edited Jan 7, 2013 at 8:03
user1822824
asked Jan 7, 2013 at 7:30
user1822824user1822824
2,5087 gold badges43 silver badges68 bronze badges
7
- This is a pretty interesting question. I think you could attract more answerers if you shortened the title. – user1726343 Commented Jan 7, 2013 at 7:33
-
4
2x * 3x = 4 / 2x
isn't really a linear equation. – Rikonator Commented Jan 7, 2013 at 7:45 - Edited title. Changed linear equations to linear equations and similar algebra problems. – user1822824 Commented Jan 7, 2013 at 8:04
-
There is a problem in your question:
2x * 3x = 4 / 2x
is not solvable using normal simplification, it is quadratic on the left side. – ATOzTOA Commented Jan 7, 2013 at 8:50 - have a look at Polish notation. – Yoshi Commented Jan 7, 2013 at 8:51
2 Answers
Reset to default 8You need to write (or use) an operator-precedence parser.
The idea is to turn the equation into a tree, e.g.
x + 3 = 3x - 2
Is really the structure
=
/ \
+ -
/ \ / \
x 3 * 2
/ \
3 x
Where each operator describes an operation between two "branches" of the tree. Using a javascript object it shouldn't be difficult to create the structure:
function tree(lterm,op,rterm) {
t.operator = op;
t.left = lterm;
t.right = rterm;
return t;
}
expression = tree("x", "/", tree("x","+",3) ); // x / (x+3)
Then by manipulating the tree you can resolve the equation, or carry out calculations. To evaluate an expression (with no unknowns), you run through the tree starting at the terminals, and upwards from intersection to intersection. You can replace a section of the tree with a result, or annotate it with a result - add a result variable to the tree
object.
Here are some useful methods to include in a tree class:
- getLeft
- getRight
- prettyPrint
- evaluate
- evaluate("x",5) // x=5, now evaluate ...
It's not just linear operations that can be "parsed" this way. Better parsers will have a list of operators that includes =*/+- but also unary operators: - ( ) sin cos...
I haven't used an operator-precedence parser in javascript, but some must exist prewritten. Surely a kind soul on this site will add a good link or two to my answer.
BTW, the tree approach has many applications. In a spreadsheet:
A2 = A1+B1
In a boolean solver:
A = not (B or C)
C = true
In XML parsing:
<main>
<part>A</part>
<part>B</part>
</main>
I have defined two functions:
getTotalX()
: It will give you the count of x
for any input string.
getTotalScalars()
: It will give you the total of scalars (numbers).
And finally, your updated code (it still does only addition and subtraction):
<script>
window.onload = function() {
// Total Xs on each side of equation
// Example problem: 5x + 2 = 10 - 2x
var leftSideXTotal = 0; // 5
var rightSideXTotal = 0; // -2
// Total integers on each side of equation
// Example problem: 5x + 2 = 10 - 2x
var leftSideIntTotal = 0; // 2
var rightSideIntTotal = 0; // 10
// Enter a math problem to solve
var problem = "5x + 2 = 10 - 2x";
// Remove all spaces in problem
// Example problem: 5x + 2 = 10 - 2x
problem = problem.replace(/\s/g,''); // 5x+2=10-2x
// Add + signs in front of all - signs
// Example problem: 5x + 2 = 10 - 2x
problem = problem.replace(/-/gi, "+-"); // 5x+2=10+-2x
// Split problem into left and right sides
// Example problem: 5x + 2 = 10 - 2x
var problemArray = problem.split("=");
var problemLeftSide = problemArray[0]; // 5x+2
var problemRightSide = problemArray[1]; // 10+-2x
leftSideXTotal = getTotalX(problemLeftSide);
leftSideIntTotal = getTotalScalars(problemLeftSide);
rightSideXTotal = getTotalX(problemRightSide);
rightSideIntTotal = getTotalScalars(problemRightSide);
// Compute
var totalXs = (leftSideXTotal - rightSideXTotal)
var totalIntegers = (rightSideIntTotal - leftSideIntTotal)
var solution = (totalIntegers / totalXs)
// Display solution
document.getElementById("divSolution").innerText = solution;
// Find the total number of X in the string
function getTotalX(data) {
data = data.replace(/\s/g,'');
xCount = 0;
if(data.indexOf('x') != -1) {
if (data.indexOf('+') != -1) {
data = data.split('+');
for(var i = 0; i < data.length; i++) {
xCount += getTotalX(data[i]);
}
} else if (data.indexOf('-') != -1) {
data = data.split('-');
// Single negative
if(data[0] == "") {
xCount -= getTotalX(data[1]);
} else {
xCount += getTotalX(data[0]);
for(var i = 1; i < data.length; i++) {
xCount -= getTotalX(data[i]);
}
}
} else {
xCount = parseInt(data.split('x')[0]);
}
}
return xCount;
}
// Find the total of scalars
function getTotalScalars(data) {
data = data.replace(/\s/g,'');
intCount = 0;
if (data.indexOf('+') != -1) {
data = data.split('+');
for(var i = 0; i < data.length; i++) {
intCount += getTotalScalars(data[i]);
}
} else if (data.indexOf('-') != -1) {
data = data.split('-');
// Single negative
if(data[0] == "") {
intCount -= getTotalScalars(data[1]);
} else {
intCount += getTotalScalars(data[0]);
for(var i = 1; i < data.length; i++) {
intCount -= getTotalScalars(data[i]);
}
}
} else {
if(data.indexOf('x') == -1) {
intCount = parseInt(data.split('x')[0]);
} else {
intCount = 0;
}
}
return intCount;
}
}
</script>