interface Number { type: "NUMBER" | string; value: number; } interface Operation { type: "OPERATION"; value: "*" | "/" | "+" | "-"; } const OPERATIONS = { "*": multiply, "/": divide, "+": add, "-": subtract } as const; const parse = (input: string): (Operation | Number)[] => input .split(" ") .map( (input: string): Number | Operation => input === "*" ? { type: "OPERATION", value: "*" } : input === "/" ? { type: "OPERATION", value: "/" } : input === "+" ? { type: "OPERATION", value: "+" } : input === "-" ? { type: "OPERATION", value: "-" } : { type: "NUMBER", value: Number(input) } ); export const combine = ({ value }: Operation, a: Number, b: Number) => ({ type: "NUMBER", value: OPERATIONS[value](a.value, b.value) }); export const doOperations = (operations: ("*" | "/" | "+" | "-")[]) => ( input: (Operation | Number)[] ) => { let result = input; const firstOperationIndex = (list: (Operation | Number)[]) => list.findIndex( ({ type, value }) => type === "OPERATION" && operations.includes(value as any) ); const operationsRemaining = (result: (Operation | Number)[]) => ~firstOperationIndex(result); while (operationsRemaining(result)) { const operationIndex = firstOperationIndex(result); const operation = result[operationIndex] as Operation; const firstNumberIndex = operationIndex - 1; const firstNumber = result[firstNumberIndex] as Number; const secondNumberIndex = operationIndex + 1; const secondNumber = result[secondNumberIndex] as Number; result = result.reduce( (result: (Operation | Number)[], current: Operation | Number, index) => { return index === operationIndex ? [...result, combine(operation, firstNumber, secondNumber)] : [firstNumberIndex, secondNumberIndex].includes(index) ? result : [...result, current]; }, [] ); } return result; }; export const calculate = pipe( parse, doOperations(["*", "/"]), doOperations(["+", "-"]), map(prop("value")), head );
Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink.
Hide child comments as well
Confirm
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Discussion on: Daily Challenge #10 - Calculator
For further actions, you may consider blocking this person and/or reporting abuse