Skip to content

Commit

Permalink
refactor: restructure fn and use better naming
Browse files Browse the repository at this point in the history
  • Loading branch information
hhow09 committed Jan 27, 2025
1 parent 11cf527 commit 77f6aa1
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 22 deletions.
2 changes: 1 addition & 1 deletion backend/src/command-service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Logger } from "pino";
import { CommandAndResult } from "./entities/command-result.entity";
import { IRepository } from "./repositories";
import { isValidCommand, evaluate } from "./math/evaluate";
import { evaluate } from "./math/evaluate";

export interface ICommandService {
evaluateAndSave(clientId: string, expression: string): Promise<string>;
Expand Down
43 changes: 27 additions & 16 deletions backend/src/math/evaluate.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
import { Summand } from './types';
const operators = new Set(['+', '-', '*', '/']);

// isValidCommand checks if the command is a allowed mathematical expression
function isValidCommand(s: string): boolean {
s = s.replace(/ /g,''); // remove all spaces
if (s.length === 0) {
// isValidOperation checks if the operation is a allowed mathematical expression
function isValidOperation(operation: string): boolean {
const cleanedOperation = operation.replace(/ /g,''); // remove all spaces
if (cleanedOperation.length === 0) {
return false;
}
// allowed characters: 0-9, +, -, *, /, .
const regex = /^[\d+\-*/.]+$/;
if (!regex.test(s)) {
if (!allowedChars(cleanedOperation)) {
return false;
}
// operators cannot be adjacent to each other
for (let i = 0; i < s.length - 1; i++) {
if (operators.has(s[i]) && operators.has(s[i + 1])) {
return false;
}
if (!noAdjacentOperators(cleanedOperation)) {
return false;
}
// operators cannot be at the end of the string
if (operators.has(s[s.length - 1])) {
if (noOperatorsAtTheEnd(cleanedOperation)) {
return false;
}
return true;
}

function allowedChars(operation: string): boolean {
return /^[\d+\-*/.]+$/.test(operation);
}

function noAdjacentOperators(operation: string): boolean {
for (let i = 0; i < operation.length - 1; i++) {
if (operators.has(operation[i]) && operators.has(operation[i + 1])) {
return false;
}
}
return true;
}

function noOperatorsAtTheEnd(operation: string): boolean {
return operators.has(operation[operation.length - 1]);
}

// evaluate evaluate a mathematical expression
function evaluate(s: string): string {
if (!isValidCommand(s)) {
if (!isValidOperation(s)) {
throw new Error('Invalid command');
}
s = s.replace(/ /g,''); // remove all spaces
Expand Down Expand Up @@ -72,4 +83,4 @@ const parseExpression = (s: string): Summand[] => {
return summands;
}

export { isValidCommand, evaluate };
export { evaluate };
10 changes: 5 additions & 5 deletions backend/src/math/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export class Fraction {
}

public add(f: Fraction): Fraction {
const commonDenominator = getLcm(this.denominator, f.denominator);
const commonDenominator = getLowestCommonMultiple(this.denominator, f.denominator);
const multiplyThis = commonDenominator.div(this.denominator);
const multiplyF = commonDenominator.div(f.denominator);
this.numerator = this.numerator.mul(multiplyThis);
Expand All @@ -95,16 +95,16 @@ export class Fraction {
}
}

function getLcm(a: Decimal, b: Decimal): Decimal {
return a.mul(b).div(getGcd(a, b));
function getLowestCommonMultiple(a: Decimal, b: Decimal): Decimal {
return a.mul(b).div(getGreatestCommonDivisor(a, b));
}

function getGcd(a: Decimal, b: Decimal): Decimal {
function getGreatestCommonDivisor(a: Decimal, b: Decimal): Decimal {
const max = Decimal.max(a, b);
const min = Decimal.min(a, b);
if (max.mod(min).eq(0)) {
return min;
} else {
return getGcd(max.mod(min), min);
return getGreatestCommonDivisor(max.mod(min), min);
}
}

0 comments on commit 77f6aa1

Please sign in to comment.