Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21,997 changes: 12,448 additions & 9,549 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-js-tutorial",
"version": "1.0.0",
"version": "1.0.1",
"description": "",
"main": "index.js",
"scripts": {
Expand Down
17 changes: 17 additions & 0 deletions src/lesson2/bracketChecker.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { bracketChecker } from "./bracketChecker";

describe("bracketChecker correct cases", () => {
it("2 ( and 2 )", () => {
expect(bracketChecker("( 5 + ( 5 + 5 ) )")).toEqual(true);
});
});

describe("bracketChecker incorrect cases, ", () => {
it("to many )", () => {
expect(bracketChecker("( 5 + ( 5 + 5 ) ) )")).toEqual(false);
});

it("to many (", () => {
expect(bracketChecker("( 5 + ( 5 + 5 )")).toEqual(false);
});
});
24 changes: 24 additions & 0 deletions src/lesson2/bracketChecker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export const openBracket = "(";
export const closeBracker = ")";

export const bracketChecker = function (line: string): boolean {
const stackForBracketCheckArray = line.split(" ");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line.split('').reduce((acc, word) => word === openBracket && acc+1, 0)

const stackForBreaket: string[] = [];

let correctOrder = true;

stackForBracketCheckArray.forEach((item) => {
if (item === openBracket) {
console.log("bracket push", item);
stackForBreaket.push(item);
} else if (item === closeBracker) {
const bracket = stackForBreaket.pop();
console.log("bracket pop", bracket);
if (bracket !== openBracket) {
correctOrder = false;
}
}
});

return stackForBreaket.length === 0 && correctOrder;
};
21 changes: 20 additions & 1 deletion src/lesson2/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,30 @@ import { ParsedLineType } from "./parser";
import { isNumber } from "./helpers";
import {
mathOperators,
singleOperators,
mathPriorities,
mathOperatorsPriorities,
} from "./mathOperators";

const [FIRST, SECOND] = mathPriorities;
const [ZERO, FIRST, SECOND] = mathPriorities;

export const zeroPrioritiesCalc = (stack: ParsedLineType): ParsedLineType =>
stack.reduce<ParsedLineType>((result, item) => {
const prevItem = result[result.length - 1];

if (isNumber(String(prevItem)) && mathOperatorsPriorities[item] === ZERO) {
if (!singleOperators[item]) {
throw new TypeError("Unexpected stack!");
}
result = [
...result.slice(0, -1),
singleOperators[item](Number(prevItem)),
];
} else {
result.push(item);
}
return result;
}, []);

export const firstPrioritiesCalc = (stack: ParsedLineType): ParsedLineType =>
stack.reduce<ParsedLineType>((result, nextItem) => {
Expand Down
2 changes: 1 addition & 1 deletion src/lesson2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const question = (): Promise<null> =>
console.log(`Result: ${result}`);
}

resolve();
resolve(null);
});
});

Expand Down
19 changes: 18 additions & 1 deletion src/lesson2/mathOperators.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { mul, div, add, minus } from "./mathOperators";
import {
mul,
div,
add,
minus,
factorial,
power,
squire,
} from "./mathOperators";

describe("mathOperators test cases", () => {
it("mul 1 * 2 to equal 2", () => {
Expand All @@ -24,4 +32,13 @@ describe("mathOperators test cases", () => {
it("minus 4 - 2 to equal 2", () => {
expect(minus(4, 2)).toBe(2);
});
it("factorial 5 to equal 120", () => {
expect(factorial(5)).toBe(120);
});
it("power 3 ^ 3 to equal 27", () => {
expect(power(3, 3)).toBe(27);
});
it("squire 3 to equal 9", () => {
expect(squire(3)).toBe(9);
});
});
33 changes: 31 additions & 2 deletions src/lesson2/mathOperators.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
export type ScalarOperationType = (first: number, second: number) => number;
export type SingleOperationType = (first: number) => number;

export const factorial: SingleOperationType = function (first: number): number {
if (first < 0) {
throw console.error("Попытка вычислить факториал отрицательного числа");
}

if (first === 0) {
return 1;
}
return first * factorial(first - 1);
};

export const squire: SingleOperationType = (first: number): number =>
first ** 2;

export const mul: ScalarOperationType = (
first: number,
Expand All @@ -20,18 +35,32 @@ export const minus: ScalarOperationType = (
second: number
): number => first - second;

export const power: ScalarOperationType = (
first: number,
second: number
): number => first ** second;

export const mathOperators: { [key: string]: ScalarOperationType } = {
"*": mul,
"/": div,
"+": add,
"-": minus,
"^": power,
};

export const singleOperators: { [key: string]: SingleOperationType } = {
"!": factorial,
"**": squire,
};

export const mathPriorities: number[] = [1, 2];
export const mathPriorities: number[] = [0, 1, 2];

const [FIRST, SECOND] = mathPriorities;
const [ZERO, FIRST, SECOND] = mathPriorities;

export const mathOperatorsPriorities: { [key: string]: number } = {
"**": ZERO,
"!": ZERO,
"^": FIRST,
"*": FIRST,
"/": FIRST,
"+": SECOND,
Expand Down
10 changes: 10 additions & 0 deletions src/lesson2/parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ describe("Parser correct cases", () => {
it("1 + 32 - 2 + 2", () => {
expect(parser("1 + 32 - 2 + 2")).toEqual([1, "+", 32, "-", 2, "+", 2]);
});
it("sequence of two single operator", () => {
expect(parser("3 ! **")).toEqual([3, "!", "**"]);
});
it("Expression with pracket", () => {
expect(parser("5 + ( 6 + 5 )")).toEqual([5, "+", "(", 6, "+", 5, ")"]);
});
});

describe("Parser invalid cases", () => {
Expand All @@ -24,4 +30,8 @@ describe("Parser invalid cases", () => {
it("1 ! 33 - 2", () => {
expect(() => parser("1 ! 33 - 2")).toThrow(TypeError("Unexpected string"));
});

it("Incorrect bracket", () => {
expect(() => parser("1 ( 4 + 4 )")).toThrow(TypeError("Unexpected string"));
});
});
44 changes: 38 additions & 6 deletions src/lesson2/parser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { isNumber } from "./helpers";
import { mathOperators } from "./mathOperators";
import { mathOperators, singleOperators } from "./mathOperators";
import { openBracket, closeBracker } from "./bracketChecker";

export type ParsedLineType = (number | string)[];

Expand All @@ -9,19 +10,50 @@ export const parser = (line: string): ParsedLineType | null => {
return stack.reduce<ParsedLineType>((result, item, key) => {
const prevItem = stack[key - 1];

const isValidNumberPush = !isNumber(prevItem) && isNumber(item);
// for numbers
const isValidNumberPush =
!isNumber(prevItem) &&
isNumber(item) &&
prevItem !== closeBracker &&
!singleOperators.hasOwnProperty(prevItem);

// for binary operators
const isValidOperatorPush =
isNumber(prevItem) &&
!isNumber(item) &&
mathOperators.hasOwnProperty(item);
isNumber(prevItem) && mathOperators.hasOwnProperty(item);

// for singleOperator
const isValidZeroOperator =
isNumber(prevItem) && singleOperators.hasOwnProperty(item);
const isSequenceOfZeroOperator =
singleOperators.hasOwnProperty(item) &&
singleOperators.hasOwnProperty(prevItem);
const isOperatorAfterZeroOperator =
mathOperators.hasOwnProperty(item) &&
singleOperators.hasOwnProperty(prevItem);

// for bracket
const isValidOpenBracket =
item === openBracket &&
(mathOperators.hasOwnProperty(prevItem) || prevItem === undefined);
const isValidCloseBracket =
item === closeBracker &&
(isNumber(prevItem) || singleOperators.hasOwnProperty(prevItem));

if (isValidNumberPush) {
result.push(Number(item));
} else if (isValidOperatorPush) {
} else if (

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if без аргумента

isValidOperatorPush ||
isValidZeroOperator ||
isSequenceOfZeroOperator ||
isOperatorAfterZeroOperator ||
isValidOpenBracket ||
isValidCloseBracket
) {
result.push(item);
} else {
throw new TypeError("Unexpected string");
}

return result;
}, []);
};
43 changes: 41 additions & 2 deletions src/lesson2/runner.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,54 @@
import { parser } from "./parser";
import { bracketChecker, closeBracker, openBracket } from "./bracketChecker";

import { firstPrioritiesCalc, secondPrioritiesCalc } from "./engine";
import {
firstPrioritiesCalc,
secondPrioritiesCalc,
zeroPrioritiesCalc,
} from "./engine";

export const runner = (line: string): number => {
const isBracketCorrect = bracketChecker(line);

if (!isBracketCorrect) {
throw console.error("bad format for bracket");
}

const stack = parser(line);

if (stack === null) {
throw new TypeError("Unexpected string");
}

const firstPrioritiesRes = firstPrioritiesCalc(stack);
const bracerStack = stack;
while (bracerStack.find((index) => index == openBracket)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

данную операцию можно упростить попробовать

const startIndex = bracerStack.findIndex((index) => index == openBracket);
const stack = [];
let lastIndex = startIndex;
stack.push(openBracket);
while (stack.length > 0) {
lastIndex++;
if (bracerStack[lastIndex] == openBracket) {
stack.push(openBracket);
} else if (bracerStack[lastIndex] == closeBracker) {
stack.pop();
}
}
const startBracer = startIndex + 1;
const bracerExpression = bracerStack.slice(startBracer, lastIndex);
const str = bracerExpression.join(" ");
const number = runner(str);

bracerStack.splice(startIndex, lastIndex - startIndex + 1, number);
}

const zeroPrioritiesRes = zeroPrioritiesCalc(stack);

if (zeroPrioritiesRes.length === 1) {
return Number(zeroPrioritiesRes[0]);
}

const firstPrioritiesRes = firstPrioritiesCalc(zeroPrioritiesRes);

if (firstPrioritiesRes.length === 1) {
return Number(firstPrioritiesRes[0]);
Expand Down
1 change: 0 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"allowJs": true,
"jsx": "react",
"sourceMap": true,
"strict": true,
Expand Down