Skip to content

Commit

Permalink
refactor: class rename
Browse files Browse the repository at this point in the history
  • Loading branch information
hhow09 committed Jan 24, 2025
1 parent 91e3b81 commit 5150267
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 17 deletions.
7 changes: 4 additions & 3 deletions backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,18 @@ src

## Math Calculation
### Evalutaion Algorithm
1. Parse the expression string by splitting by `+` and `-`, resulting a list of sub-expressions (`ExpressionMD`).
2. For each sub-expression, turn it into a `Fraction`.
1. Parse the expression string by splitting by `+` and `-`, resulting a list of sub-expressions (`Summand`).
2. For each `Summand`, turn it into a `Fraction`.
3. Sum all fractions by `Fraction.add(Fraction)`.
- It uses **lowest common multiple** to add fractions.
- [Decimal.js](https://mikemcl.github.io/decimal.js/) is used for the basic arithmetic operations.
4. Evaluate the result by `Fraction.evaluate()`.
- result is converted to string to avoid overflow and keep precision.

### Example
1. Input string: `5 / 3 / 4 * 9 - 2 * 3 / 8`
2. Parse into sub-expressions: `5 / 3 / 4 * 9` and `-2 * 3 / 8`
3. Turn these into fractions: $\frac{5 * 9}{3 * 4}$ and $-\frac{2 * 3}{8}$
3. Turn them into fractions: $\frac{5 * 9}{3 * 4}$ and $-\frac{2 * 3}{8}$
4. find equivalent fractions with same denominator: $\frac{90}{24}$ and $-\frac{18}{24}$
5. Sum these fractions: $\frac{90}{24} - \frac{18}{24} = \frac{72}{24} = 3$

Expand Down
25 changes: 13 additions & 12 deletions backend/src/math/evaluate.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExpressionMD } from './types';
import { Summand } from './types';
const operators = new Set(['+', '-', '*', '/']);

// isValidCommand checks if the command is a allowed mathematical expression
Expand Down Expand Up @@ -32,22 +32,23 @@ function evaluate(s: string): string {
}
s = s.replace(/ /g,''); // remove all spaces

const exps = parseExpressionMDs(s).map(expMD => expMD.toFraction());
const first = exps.shift();
const summands = parseExpression(s);
const fractions = summands.map(expMD => expMD.toFraction());
const first = fractions.shift();
if (!first) {
return "0"
}
// early return
if (exps.length === 0) {
if (fractions.length === 0) {
return first.evaluate()
}
const result = exps.reduce((acc, expMD) => acc.add(expMD), first);
const result = fractions.reduce((acc, f) => acc.add(f), first);
return result.evaluate().toString();
}

// parseExpressionMDs parse the expression into list of ExpressionMD
const parseExpressionMDs = (s: string): ExpressionMD[] => {
const expressions: ExpressionMD[] = [];
// parseExpression parse the expression into list of Summand
const parseExpression = (s: string): Summand[] => {
const summands: Summand[] = [];
let currExp = "";
let prevOp = true;
if (s[0] === '-') {
Expand All @@ -56,19 +57,19 @@ const parseExpressionMDs = (s: string): ExpressionMD[] => {
}
for (const token of s.split('')) {
if (token === '+') {
expressions.push(new ExpressionMD(prevOp, currExp));
summands.push(new Summand(prevOp, currExp));
prevOp = true
currExp = "";
} else if (token === '-') {
expressions.push(new ExpressionMD(prevOp, currExp));
summands.push(new Summand(prevOp, currExp));
prevOp = false;
currExp = "";
} else {
currExp += token;
}
}
expressions.push(new ExpressionMD(prevOp, currExp)); // last one
return expressions;
summands.push(new Summand(prevOp, currExp)); // last token
return summands;
}

export { isValidCommand, evaluate };
6 changes: 4 additions & 2 deletions backend/src/math/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Decimal } from "decimal.js";

// ExpressionMD is a mathematical expression only contains numbers, multiplication, division
export class ExpressionMD {
// Summand is a mathematical expression only contains numbers, multiplication, division
export class Summand {
public sign: boolean;
public exp: string;
constructor(sign: boolean, exp: string) {
Expand All @@ -21,6 +21,8 @@ export class ExpressionMD {
if (indexOfFirstOperator === this.exp.length) {
return new Fraction(numerator, new Decimal(1));
}

// parse the expression of multiplication and division
let prevOp = this.exp[indexOfFirstOperator];
let currStr = "";
for (let i = indexOfFirstOperator + 1; i < this.exp.length; i++) {
Expand Down

0 comments on commit 5150267

Please sign in to comment.