-
Notifications
You must be signed in to change notification settings - Fork 0
<fix> Normalise quotients to form a/b * c #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
cb831d4
5605f1d
ad72917
95fab4f
de363be
2ddd1e7
88ed1f2
324a061
1d1250c
f838183
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,6 @@ | ||||||||||||||||||||||||||||||
| // TODO: Eventually, put this in a separate file | ||||||||||||||||||||||||||||||
| let RAW_SOLUTION = "1/2 x^2 sin(2x) + 1/2 x cos(2x) - 1/4 sin(2x) + c"; | ||||||||||||||||||||||||||||||
| let SOLUTION = normaliseTree(strToTree(RAW_SOLUTION)); | ||||||||||||||||||||||||||||||
| let SOLUTION = normaliseTree(strToTree(RAW_SOLUTION)); // TODO: Add normaliseTree back | ||||||||||||||||||||||||||||||
| let answerText = document.getElementById("answerText"); // Answer that appears on win modal | ||||||||||||||||||||||||||||||
| answerText.innerText = `\\(${RAW_SOLUTION}\\)`; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
@@ -382,7 +382,101 @@ function postfixToTree(components, index=0, parentIndex=-1, depth=0) | |||||||||||||||||||||||||||||
| // RETURNS: list normalised tree | ||||||||||||||||||||||||||||||
| function normaliseTree(tree, rootNodeIndex=0) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| let currentNodeIndex = rootNodeIndex; | ||||||||||||||||||||||||||||||
| // Convert all quotients to form a/b * c | ||||||||||||||||||||||||||||||
| let currentNodeIndex = 0; | ||||||||||||||||||||||||||||||
| while (currentNodeIndex != -1) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| // Check quotient is in form ac/b, and needs to be transformed | ||||||||||||||||||||||||||||||
| // (Current node is /, and right child is *) | ||||||||||||||||||||||||||||||
| let currentNode = tree.Get(currentNodeIndex); | ||||||||||||||||||||||||||||||
| if (!checkDividendIsProduct(tree, currentNode)) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| currentNodeIndex = findNextInDFS(tree, 0, currentNodeIndex); | ||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| let divisionNode = currentNode; | ||||||||||||||||||||||||||||||
| // Make a (right child of *) the right child of / | ||||||||||||||||||||||||||||||
| let multiplicationNode = tree.Get(divisionNode.rightNode); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // If / is root node, we need to make * root node | ||||||||||||||||||||||||||||||
| if (tree.Find(currentNode) == tree.root) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| tree.root = tree.Find(multiplyNode); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // If not, make * the child of /'s parent | ||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| let divisionNodeParent = tree.Get(divisionNode.parent); | ||||||||||||||||||||||||||||||
| if (divisionNodeParent.leftNode == tree.Find(divisionNode)) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| divisionNodeParent.leftNode = tree.Find(multiplicationNode); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| else if (divisionNodeParent.rightNode == tree.Find(divisionNode)) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| divisionNodeParent.rightNode = tree.Find(multiplicationNode); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| divisionNode.rightNode = multiplicationNode.rightNode; | ||||||||||||||||||||||||||||||
| let a = tree.Get(divisionNode.rightNode); | ||||||||||||||||||||||||||||||
| a.parent = tree.Find(divisionNode); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Make / the right child of * | ||||||||||||||||||||||||||||||
| multiplicationNode.rightNode = tree.Find(divisionNode); | ||||||||||||||||||||||||||||||
| divisionNode.parent = tree.Find(multiplicationNode); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // TODO: If / is at front of list, we need to swap the / and * around. | ||||||||||||||||||||||||||||||
| currentNodeIndex = findNextInDFS(tree, 0, tree.Find(divisionNode)); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Convert all quotients to form 1/b * a | ||||||||||||||||||||||||||||||
| currentNodeIndex = 0; | ||||||||||||||||||||||||||||||
| while (currentNodeIndex != -1) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| let currentNode = tree.Get(currentNodeIndex); | ||||||||||||||||||||||||||||||
| if (!checkDividendIsNot1(tree, currentNode)) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| currentNodeIndex = findNextInDFS(tree, 0, currentNodeIndex); | ||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| let a = tree.Get(currentNode.rightNode); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Add * node | ||||||||||||||||||||||||||||||
| let multiplyNode = new Node("operator", Operator.MULTIPLICATION, leftNode=tree.Find(a), rightNode=currentNodeIndex); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // If / is root node, we need to make * root node | ||||||||||||||||||||||||||||||
| if (tree.Find(currentNode) == tree.root) | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| tree.AddAsRoot(multiplyNode); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // If not, make * the right node of its parent | ||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| let multiplyNodeParent = tree.Get(currentNode.parent); | ||||||||||||||||||||||||||||||
| multiplyNodeParent.rightNode = -1; | ||||||||||||||||||||||||||||||
| tree.Add(multiplyNode, multiplyNodeParent); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| currentNode.parent = tree.Find(multiplyNode); | ||||||||||||||||||||||||||||||
| a.parent = tree.Find(multiplyNode); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Add 1 node | ||||||||||||||||||||||||||||||
| let oneNode = newNode("number", '1'); | ||||||||||||||||||||||||||||||
| tree.Add(oneNode, currentNode); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| currentNode.rightNode = tree.Find(oneNode); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Change current node index to index of * (to traverse over a) | ||||||||||||||||||||||||||||||
| currentNodeIndex = tree.Find(multiplyNode); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
Comment on lines
473
to
475
|
||||||||||||||||||||||||||||||
| // Change current node index to index of * (to traverse over a) | |
| currentNodeIndex = tree.indexOf(multiplyNode); | |
| // Move to the next node in DFS after the updated current node |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function name uses "dividend" but it should be "divisor". In the expression a/b, "a" is the dividend (numerator) and "b" is the divisor (denominator). This function checks if the right child (which represents "a" in the tree structure) is a product, but the comment and function name are misleading. The function should be named checkDivisorIsProduct or the comment should clarify the tree structure.
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment has a typo: "true is dividend" should be "true if dividend".
| // RETURNS: bool true is dividend is not 1, false if it is | |
| // RETURNS: bool true if dividend is not 1, false if it is |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment refers to "is dividend" but should say "its dividend" for proper grammar.
| // Checks whether current node is a /, and is dividend is something other than 1 | |
| // Essentially, checks for divisions in the form of a/b (as these need to be normalised to 1/b * a) | |
| // INPUTS: tree, node in tree | |
| // RETURNS: bool true is dividend is not 1, false if it is | |
| // Checks whether current node is a /, and its dividend is something other than 1 | |
| // Essentially, checks for divisions in the form of a/b (as these need to be normalised to 1/b * a) | |
| // INPUTS: tree, node in tree | |
| // RETURNS: bool true if its dividend is not 1, false if it is |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly to checkDividendIsProduct, this function name uses "dividend" but should use "divisor" for mathematical accuracy. In a/b, the function checks if "a" (the right node) is not "1", but "a" would be the divisor in the tree representation, not the dividend. The function should be named checkDivisorIsNot1 for clarity.
| // Checks whether current node is a /, and is dividend is something other than 1 | |
| // Essentially, checks for divisions in the form of a/b (as these need to be normalised to 1/b * a) | |
| // INPUTS: tree, node in tree | |
| // RETURNS: bool true is dividend is not 1, false if it is | |
| function checkDividendIsNot1(tree, node) | |
| { | |
| // Check if node is /, and right child is not 1 | |
| // Checks whether current node is a /, and its divisor is something other than 1. | |
| // Essentially, checks for divisions in the form of a/b (as these need to be normalised to 1/b * a). | |
| // INPUTS: tree, node in tree | |
| // RETURNS: bool true if divisor is not 1, false if it is | |
| function checkDivisorIsNot1(tree, node) | |
| { | |
| // Check if node is /, and right child (the divisor) is not 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment indentation is inconsistent - it should be aligned with the rest of the code block. This line appears to have extra leading tabs.