Javascript Leetcode Examples
Javascript Leetcode Examples
Write a function createHelloWorld. It should return a new function that always returns "Hello World".
Example 1:
Input: args = []
Output: "Hello World"
Explanation:
const f = createHelloWorld();
f(); // "Hello World"
Example 2:
Any arguments could be passed to the function but it should still always return "Hello World".
2620. Counter
Given an integer n, return a counter function. This counter function initially returns n and then returns 1 more than
the previous value every subsequent time it is called ( n, n + 1, n + 2, etc).
Example 1:
Input:
n = 10
["call","call","call"]
Output: [10,11,12]
Explanation:
counter() = 10 // The first time counter() is called, it returns n.
counter() = 11 // Returns 1 more than the previous time.
counter() = 12 // Returns 1 more than the previous time.
Example 2:
Input:
n = -2
["call","call","call","call","call"]
Output: [-2,-1,0,1,2]
Explanation: counter() initially returns -2. Then increases after each sebsequent call.
};
What is Closure ?
A closure is created when a function is defined inside another function, and the inner
function references variables in the outer function's scope. When the inner function is
returned from the outer function, it retains a reference to the outer function's scope, and can
continue to access those variables even after the outer function has finished executing. Vice-
Versa is not true!!
In simple terms a closure can "remember" values from its outer function's scope and use
them later, even if the outer function has returned and those values would normally be out
of scope.
From definition you can see that it's used for retrival of values from outer parent function so
we can understand that closure can be used for retrival of dead values which have become
out of scope. also we can comprehend that it can used for privating some varibles or function.
Thus closures are useful for creating private variables and functions, implementing
partial function application, and preserving state in asynchronous code.
While writing the code whenever there is a need for these types of thing try to incorporate
this closure concept i.e. In a programmer languge it's called lexical environment
return () => {
count++;
console.log(count);
}
}
In this example, makeCounter is an arrow function that returns another arrow function. The returned
function increments a count variable each time it is called, and logs the new value of count to
the console.
When makeCounter is called, it creates a new scope with a count variable initialized to 0. It then
returns a new arrow function that "closes over" this scope and increments the count
variable each time it is called.
When we assign the returned arrow function to the counter variable, we create a closure that
retains a reference to the count variable.
Each time we call counter(), it increments the count variable and logs the new value to the
console, because it is still "closing over" the original count variable in the outer function's
scope.
Thus because the count variable is not exposed outside of the returned object, it is effectively
a private variable that can only be accessed or modified through the makeCounter() methods.
2. Partial function:
I was introduced to this concept name during development phase but was shocked that
unknowingly I have used it many times. I'm sure that you all also must have use this:
function add(x) {
return function(y) {
return x + y;
}
}
In this example, the add() function returns another function that takes a single argument and
returns the sum of that argument and the x value from the outer function's scope.
This allows us to "partially apply" the add() function by passing in an x value and getting back
a new function that always adds that value to its argument.
Thuse we can then use the new function like any other function, passing in different y values
as needed.
3. For preserving states in asynchronous code:
The below snippet is from my personal project:)
const animate = (element, from, to, duration) => {
let start = performance.now();
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
In this example, the animate() function creates a closure over the start variable, which is used to
calculate the elapsed time since the animation started.
The update() function also "closes over" the element, from, to, and duration arguments, so that it
can use them to update the element's position over time.
Thus by creating a closure over these values, we can preserve their state between
animation frames, even though the update() function is
called asynchronously by requestAnimationFrame().
To Be Or Not To Be
Write a function expect that helps developers test their code. It should take in any value val and return an object
with the following two functions.
toBe(val) accepts another value and returns true if the two values === each other. If they are not equal, it
should throw an error "Not Equal".
notToBe(val) accepts another value and returns true if the two values !== each other. If they are equal, it
should throw an error "Equal".
Example 1:
Example 3:
Solution:
The problem requires the expect function to support making toBe and notToBe calls (e.g., expect(5).toBe(5); should
return true, and expect(5).notToBe(5); should throw "Equal"). To do so, we should define the return of the expect
function based on what kind of call we make. This can be done in the following format:
return {
},
The below solution follows this format, where toBe and notToBe both has an if else statement, such that if the throw
condition is true, throw an error. Otherwise, return true.
Code
return {
},
};
Counter II
Write a function createCounter. It should accept an initial integer init. It should return an object with three functions.
Example 1:
Example 2:
function increment() {
return ++presentCount;
}
function decrement() {
return --presentCount;
}
function reset() {
return (presentCount = init);
}
In ES6, classes were introduced as syntactic sugar over the prototype-based inheritance model
but shortly after that It provided a way to support inheritance and can have static
methods and properties, getters and setters, and more. Thus they provided a way to write
object-oriented code in a more concise and organized way.
o The constructor method is a special method that is called when an object is created based on
the class.
o It initializes the object with properties init and presentCount.
The increment(), decrement()and reset() method are regular methods that can be called on an
instance of the Counter class to get the output
o To create an object based on a class we use the new operator i.e. we create an object
called createCounter based on the Counter class, passing in the init value as arguments to the
constructor.
class Counter {
constructor(init) {
this.init = init;
this.presentCount = init;
}
increment() {
this.presentCount += 1;
return this.presentCount;
}
decrement() {
this.presentCount -= 1;
return this.presentCount;
}
reset() {
this.presentCount = this.init;
return this.presentCount;
}
}
Given an integer array arr and a mapping function fn, return a new array with a transformation applied to each
element.
The returned array should be created such that returnedArray[i] = fn(arr[i], i).
Example 1:
Example 2:
Example 3:
Solution:
Given an integer array arr and a filtering function fn, return a filtered array filteredArr.
filteredArr should only contain the elements from the arr for which the expression fn(arr[i], i) evaluates to
a truthy value. A truthy value is a value where Boolean(value) returns true.
Example 1:
Example 2:
Input: arr = [1,2,3], fn = function firstIndex(n, i) { return i === 0; }
Output: [1]
Explanation:
fn can also accept the index of each element
In this case, the function removes elements not at index 0
Solution:
Code in JavaScript
/**
* @param {number[]} arr
* @param {Function} fn
* @return {number[]}
*/
var filter = function(arr, fn) {
var filteredArr = [];
for (var i = 0; i < arr.length; i++) {
if (fn(arr[i], i)) {
filteredArr.push(arr[i]);
}
}
return filteredArr;
};
Code in TypeScript
type FilterFn<T> = (element: T, index?: number, array?: T[]) => boolean;
Given an integer array nums, a reducer function fn, and an initial value init, return a reduced array.
A reduced array is created by applying the following operation: val = fn(init, nums[0]), val = fn(val, nums[1]), val =
fn(val, nums[2]), ... until every element in the array has been processed. The final value of val is returned.
Input:
nums = [1,2,3,4]
fn = function sum(accum, curr) { return accum + curr; }
init = 0
Output: 10
Explanation:
initially, the value is init=0.
(0) + nums[0] = 1
(1) + nums[1] = 3
(3) + nums[2] = 6
(6) + nums[3] = 10
The final answer is 10.
Example 2:
Input:
nums = [1,2,3,4]
fn = function sum(accum, curr) { return accum + curr * curr; }
init = 100
Output: 130
Explanation:
initially, the value is init=100.
(100) + nums[0]^2 = 101
(101) + nums[1]^2 = 105
(105) + nums[2]^2 = 114
(114) + nums[3]^2 = 130
The final answer is 130.
Solution:
Code In JavaScript
/**
* @param {number[]} nums
* @param {Function} fn
* @param {number} init
* @return {number}
*/
var reduce = function(nums, fn, init) {
let val = init;
for (let i = 0; i < nums.length; i++) {
val = fn(val, nums[i]);
}
return val;
};
Code In TypeScript
type Reducer<T, U> = (acc: T, curr: U) => T;
Function Composition
Given an array of functions [f1, f , f , ..., f ], return a new function fn that is the function composition of the array of
2 3 n
functions.
The function composition of an empty list of functions is the identity function f(x) = x.
You may assume each function in the array accepts one integer as input and returns one integer as output.
Example 1:
Example 2:
Solution:
Code In JS
/**
* @param {Function[]} functions
* @return {Function}
*/
var compose = function(functions) {
if (functions.length === 0) {
return function(x) { return x; };
}
};
Write a function argumentsLength that returns the count of arguments passed to it.
Example 1:
Example 2:
Solution:
var argumentsLength = function(...args) {
return args.length
};
/**
* argumentsLength(1, 2, 3); // 3
*/
The first time the returned function is called, it should return the same result as fn.
Every subsequent time it is called, it should return undefined.
Example 1:
Example 2:
Solution:
/**
* @param {Function} fn
* @return {Function}
*/
var once = function(fn) {
return function(...args) {
if (!hasBeenCalled) {
result = fn(...args);
hasBeenCalled = true;
return result;
} else {
return undefined;
}
}
};
console.log(onceFn(1,2,3)); // 6
console.log(onceFn(2,3,6)); // undefined
Memoize
A memoized function is a function that will never be called twice with the same inputs. Instead it will return a
cached value.
You can assume there are 3 possible input functions: sum, fib, and factorial.
Example 1:
Input
"sum"
["call","call","getCallCount","call","getCallCount"]
[[2,2],[2,2],[],[1,2],[]]
Output
[4,4,1,3,2]
/**
* @param {Function} fn
*/
function memoize(fn) {
return function(...args) {
const key = JSON.stringify(args);
if (key in cache) {
return cache[key];
}
return result;
}
}
Given two promises promise1 and promise2, return a new promise. promise1 and promise2 will both resolve with a
number. The returned promise should resolve with the sum of the two numbers.
Example 1:
Input:
promise1 = new Promise(resolve => setTimeout(() => resolve(2), 20)),
promise2 = new Promise(resolve => setTimeout(() => resolve(5), 60))
Output: 7
Explanation: The two input promises resolve with the values of 2 and 5 respectively. The returned promise should
resolve with a value of 2 + 5 = 7. The time the returned promise resolves is not judged for this problem.
Example 2:
Input:
promise1 = new Promise(resolve => setTimeout(() => resolve(10), 50)),
promise2 = new Promise(resolve => setTimeout(() => resolve(-12), 30))
Output: -2
Explanation: The two input promises resolve with the values of 10 and -12 respectively. The returned promise
should resolve with a value of 10 + -12 = -2.
Solution:
/**
* @param {Promise} promise1
* @param {Promise} promise2
* @return {Promise}
*/
var addTwoPromises = async function(promise1, promise2) {
// Wait for both promises to resolve and retrieve their values
const [value1, value2] = await Promise.all([promise1, promise2]);
// Return a new promise that resolves with the sum of the values
return value1 + value2;
};
// // Example usage:
// var promise1 = new Promise(resolve => setTimeout(() => resolve(2), 20));
// var promise2 = new Promise(resolve => setTimeout(() => resolve(5), 60));
// addTwoPromises(promise1, promise2)
// .then(console.log); // Output: 7
Sleep
Given a positive integer millis, write an asynchronous function that sleeps for millis milliseconds. It can resolve any
value.
Example 1:
Example 2:
Solution:
/**
* @param {number} millis
*/
async function sleep(millis) {
await new Promise(resolve => setTimeout(resolve, millis));
}
/**
* let t = Date.now()
* sleep(100).then(() => console.log(Date.now() - t)) // 100
*/
If the fn completes within the time limit of t milliseconds, the time limited function should resolve with the
result.
If the execution of the fn exceeds the time limit, the time limited function should reject with the
string "Time Limit Exceeded".
Example 1:
Input:
fn = async (n) => {
await new Promise(res => setTimeout(res, 100));
return n * n;
}
inputs = [5]
t = 50
Output: {"rejected":"Time Limit Exceeded","time":50}
Explanation:
const limited = timeLimit(fn, t)
const start = performance.now()
let result;
try {
const res = await limited(...inputs)
result = {"resolved": res, "time": Math.floor(performance.now() - start)};
} catch (err) {
result = {"rejected": err, "time": Math.floor(performance.now() - start)};
}
console.log(result) // Output
The provided function is set to resolve after 100ms. However, the time limit is set to 50ms. It rejects at t=50ms
because the time limit was reached.
Example 2:
Input:
fn = async (n) => {
await new Promise(res => setTimeout(res, 100));
return n * n;
}
inputs = [5]
t = 150
Output: {"resolved":25,"time":100}
Explanation:
The function resolved 5 * 5 = 25 at t=100ms. The time limit is never reached.
Solution:
/**
* @param {Function} fn
* @param {number} t
* @return {Function}
*/
var timeLimit = function(fn, t) {
return async function(...args) {
const originalFnPromise = fn(...args);
Debounce
Given a function fn and a time in milliseconds t, return a debounced version of that function.
A debounced function is a function whose execution is delayed by t milliseconds and whose execution is cancelled
if it is called again within that window of time. The debounced function should also receive the passed parameters.
For example, let's say t = 50ms, and the function was called at 30ms, 60ms, and 100ms. The first 2 function calls
would be cancelled, and the 3rd function call would be executed at 150ms. If instead t = 35ms, The 1st call would
be cancelled, the 2nd would be executed at 95ms, and the 3rd would be executed at 135ms.
The above diagram shows how debounce will transform events. Each rectangle represents 100ms and the
debounce time is 400ms. Each color represents a different set of inputs.
Example 1:
Input:
t = 50
calls = [
{"t": 50, inputs: [1]},
{"t": 75, inputs: [2]}
]
Output: [{"t": 125, inputs: [2]}]
Solution:
var debounce = function(fn, t = 1000) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), t);
}
};
Given an array of asynchronous functions functions, return a new promise promise. Each function in the array
accepts no arguments and returns a promise.
promise resolves:
When all the promises returned from functions were resolved successfully. The resolved value
of promise should be an array of all the resolved values of promises in the same order as they were in
the functions.
promise rejects:
When any of the promises returned from functions were rejected. promise should also reject with the reason
of the first rejection.
Example 1:
Input: functions = [
() => new Promise(resolve => setTimeout(() => resolve(5), 200))
]
Output: {"t": 200, "resolved": [5]}
Explanation:
promiseAll(functions).then(console.log); // [5]
Input: functions = [
() => new Promise(resolve => setTimeout(() => resolve(1), 200)),
() => new Promise((resolve, reject) => setTimeout(() => reject("Error"), 100))
]
Output: {"t": 100, "rejected": "Error"}
Explanation: Since one of the promises rejected, the returned promise also rejected with the same error at the
same time.
Solution:
/**
* @param {Array<Function>} functions
* @return {Promise<any>}
*/
var promiseAll = async function(functions) {
return new Promise((resolve, reject) => {
// We know the resulting array will be the same length as functions
const results = new Array(functions.length);
let count = 0;
functions.forEach((fn, i) => {
fn()
.then(val => {
results[i] = val;
count++;
if(count === functions.length) resolve(results);
})
.catch(reason => reject(reason));
});
});
};
/**
* const promise = promiseAll([() => new Promise(res => res(42))])
* promise.then(console.log); // [42]
*/
Is Object Empty
Example 1:
Input: obj = {"x": 5, "y": 42}
Output: false
Explanation: The object has 2 key-value pairs so it is not empty.
Example 2:
Input: obj = {}
Output: true
Explanation: The object doesn't have any key-value pairs so it is empty.
Example 3:
Chunk Array
Given an array arr and a chunk size size, return a chunked array. A chunked array contains the original elements
in arr, but consists of subarrays each of length size. The length of the last subarray may be less
than size if arr.length is not evenly divisible by size.
You may assume the array is the output of JSON.parse. In other words, it is valid JSON.
Example 1:
Example 2:
Write code that enhances all arrays such that you can call the array.last() method on any array and it will return the
last element. If there are no elements in the array, it should return -1.
Example 1:
Example 2:
Input: nums = []
Output: -1
Explanation: Because there are no elements, return -1
Array.prototype.last = function() {
if (this.length === 0) {
return -1;
} else {
return this[this.length - 1];
}
};
Group By
Write code that enhances all arrays such that you can call the array.groupBy(fn) method on any array and it will
return a grouped version of the array.
A grouped array is an object where each key is the output of fn(arr[i]) and each value is an array containing all
items in the original array with that key.
The provided callback fn will accept an item in the array and return a string key.
The order of each value list should be the order the items appear in the array. Any order of keys is acceptable.
Example 1:
Input:
array = [
{"id":"1"},
{"id":"1"},
{"id":"2"}
],
fn = function (item) {
return item.id;
}
Output:
{
"1": [{"id": "1"}, {"id": "1"}],
"2": [{"id": "2"}]
}
/**
* @param {Function} fn
* @return {Array}
*/
Array.prototype.groupBy = function(fn) {
// Reduce the array into a single object
return this.reduce((grouped, item) => {
// Apply the provided callback function to get the key
const key = fn(item);
// If the key doesn't exist in the grouped object, create a new array for it
if (!grouped[key]) {
grouped[key] = [];
}
// Push the current item to the array associated with the key
grouped[key].push(item);
/**
* [1,2,3].groupBy(String) // {"1":[1],"2":[2],"3":[3]}
*/
Sort By
Given an array arr and a function fn, return a sorted array sortedArr. You can assume fn only returns numbers and
those numbers determine the sort order of sortedArr. sortedArray must be sorted in ascending order by fn output.
You may assume that fn will never duplicate numbers for a given array.
Example 1:
Example 2:
Input: arr = [{"x": 1}, {"x": 0}, {"x": -1}], fn = (d) => d.x
Output: [{"x": -1}, {"x": 0}, {"x": 1}]
Explanation: fn returns the value for the "x" key. So the array is sorted based on that value.
/**
* @param {Array} arr
* @param {Function} fn
* @return {Array}
*/
const sortBy = (arr, fn) => Array.from(arr).sort((a, b) => fn(a) > fn(b) ? 1 : -1);
Given two arrays arr1 and arr2, return a new array joinedArray. All the objects in each of the two inputs arrays will
contain an id field that has an integer value. joinedArray is an array formed by merging arr1 and arr2 based
on their id key. The length of joinedArray should be the length of unique values of id. The returned array should be
sorted in ascending order based on the id key.
If a given id exists in one array but not the other, the single object with that id should be included in the result
array without modification.
If two objects share an id, their properties should be merged into a single object:
If a key only exists in one object, that single key-value pair should be included in the object.
If a key is included in both objects, the value in the object from arr2 should override the value from arr1.
Example 1:
Input:
arr1 = [
{"id": 1, "x": 1},
{"id": 2, "x": 9}
],
arr2 = [
{"id": 3, "x": 5}
]
Output:
[
{"id": 1, "x": 1},
{"id": 2, "x": 9},
{"id": 3, "x": 5}
]
Explanation: There are no duplicate ids so arr1 is simply concatenated with arr2.
Example 2:
Input:
arr1 = [
{"id": 1, "x": 2, "y": 3},
{"id": 2, "x": 3, "y": 6}
],
arr2 = [
{"id": 2, "x": 10, "y": 20},
{"id": 3, "x": 0, "y": 0}
]
Output:
[
{"id": 1, "x": 2, "y": 3},
{"id": 2, "x": 10, "y": 20},
{"id": 3, "x": 0, "y": 0}
]
/**
* @param {Array} arr1
* @param {Array} arr2
* @return {Array}
*/
var join = function(arr1, arr2) {
const result = {};
for (let i = 0; i < arr1.length; i++) {
result[arr1[i].id] = arr1[i];
}
for (let i = 0; i < arr2.length; i++) {
if (result[arr2[i].id]) {
for (const key in arr2[i]) result[arr2[i].id][key] = arr2[i][key];
} else {
result[arr2[i].id] = arr2[i];
}
}
return Object.values(result);
};
Flatten Deeply Nested Array
Given a multi-dimensional array arr and a depth n, return a flattened version of that array.
A multi-dimensional array is a recursive data structure that contains integers or other multi-dimensional arrays.
A flattened array is a version of that array with some or all of the sub-arrays removed and replaced with the actual
elements in that sub-array. This flattening operation should only be done if the current depth of nesting is
less than n. The depth of the elements in the first array are considered to be 0.
Example 1:
Input
arr = [1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]]
n=0
Output
[1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]]
Explanation
Passing a depth of n=0 will always result in the original array. This is because the smallest possible depth of a
subarray (0) is not less than n=0. Thus, no subarray should be flattened.
Example 2:
Input
arr = [1, 2, 3, [4, 5, 6], [7, 8, [9, 10, 11], 12], [13, 14, 15]]
n=1
Output
[1, 2, 3, 4, 5, 6, 7, 8, [9, 10, 11], 12, 13, 14, 15]
/**
* @param {any[]} arr
* @param {number} depth
* @return {any[]}
*/
var flat = function(arr, depth) {
const stack = [...arr.map(item => [item, depth])];
const result = [];
return result.reverse();
};
Compact Object
Given an object or array obj, return a compact object. A compact object is the same as the original object, except
with keys containing falsy values removed. This operation applies to the object and any nested objects. Arrays are
considered objects where the indices are keys. A value is considered falsy when Boolean(value) returns false.
You may assume the obj is the output of JSON.parse. In other words, it is valid JSON.
Example 1:
Example 2:
return compacted;
};
Event Emitter
Design an EventEmitter class. This interface is similar (but with some differences) to the one found in Node.js or the
Event Target interface of the DOM. The EventEmitter should allow for subscribing to events and emitting them.
subscribe - This method takes in two arguments: the name of an event as a string and a callback function.
This callback function will later be called when the event is emitted.
An event should be able to have multiple listeners for the same event. When emitting an event with
multiple callbacks, each should be called in the order in which they were subscribed. An array of results
should be returned. You can assume no callbacks passed to subscribe are referentially identical.
The subscribe method should also return an object with an unsubscribe method that enables the user to
unsubscribe. When it is called, the callback should be removed from the list of subscriptions
and undefined should be returned.
emit - This method takes in two arguments: the name of an event as a string and an optional array of
arguments that will be passed to the callback(s). If there are no callbacks subscribed to the given event,
return an empty array. Otherwise, return an array of the results of all callback calls in the order they were
subscribed.
Example 1:
Input:
actions = ["EventEmitter", "emit", "subscribe", "subscribe", "emit"],
values = [[], ["firstEvent", "function cb1() { return 5; }"], ["firstEvent", "function cb1() { return 6; }"], ["firstEvent"]]
Output: [[],["emitted",[]],["subscribed"],["subscribed"],["emitted",[5,6]]]
Explanation:
const emitter = new EventEmitter();
emitter.emit("firstEvent"); // [], no callback are subscribed yet
emitter.subscribe("firstEvent", function cb1() { return 5; });
emitter.subscribe("firstEvent", function cb2() { return 6; });
emitter.emit("firstEvent"); // [5, 6], returns the output of cb1 and cb2
Example 2:
Input:
actions = ["EventEmitter", "subscribe", "emit", "emit"],
values = [[], ["firstEvent", "function cb1(...args) { return args.join(','); }"], ["firstEvent", [1,2,3]], ["firstEvent", [3,4,6]]]
Output: [[],["subscribed"],["emitted",["1,2,3"]],["emitted",["3,4,6"]]]
Explanation: Note that the emit method should be able to accept an OPTIONAL array of arguments.
class EventEmitter {
constructor() {
this.events = new Map();
}
subscribe(event, cb) {
if (!this.events.has(event)) {
this.events.set(event, []);
}
return {
unsubscribe: () => {
const index = listeners.indexOf(cb);
if (index !== -1) {
listeners.splice(index, 1);
}
}
};
}
return results;
}
}
Array Wrapper
Create a class ArrayWrapper that accepts an array of integers in its constructor. This class should have two features:
When two instances of this class are added together with the + operator, the resulting value is the sum of
all the elements in both arrays.
When the String() function is called on the instance, it will return a comma separated string surrounded by
brackets. For example, [1,2,3].
Example 1:
/**
* @param {number[]} nums
*/
var ArrayWrapper = function(nums) {
this.nums = nums;
};
ArrayWrapper.prototype.valueOf = function() {
return this.nums.reduce((sum, num) => sum + num, 0);
}
ArrayWrapper.prototype.toString = function() {
return `[${this.nums.join(',')}]`;
}
/**
* const obj1 = new ArrayWrapper([1,2]);
* const obj2 = new ArrayWrapper([3,4]);
* obj1 + obj2; // 10
* String(obj1); // "[1,2]"
* String(obj2); // "[3,4]"
*/
Design a Calculator class. The class should provide the mathematical operations of addition, subtraction,
multiplication, division, and exponentiation. It should also allow consecutive operations to be performed using
method chaining. The Calculator class constructor should accept a number which serves as the initial value of result.
add - This method adds the given number value to the result and returns the updated Calculator.
subtract - This method subtracts the given number value from the result and returns the updated Calculator.
multiply - This method multiplies the result by the given number value and returns the updated Calculator.
divide - This method divides the result by the given number value and returns the updated Calculator. If the
passed value is 0, an error "Division by zero is not allowed" should be thrown.
power - This method raises the result to the power of the given number value and returns the
updated Calculator.
getResult - This method returns the result.
Solutions within 10 of the actual result are considered correct.
-5
Example 1:
Input:
actions = ["Calculator", "add", "subtract", "getResult"],
values = [10, 5, 7]
Output: 8
Explanation:
new Calculator(10).add(5).subtract(7).getResult() // 10 + 5 - 7 = 8
Example 2:
Input:
actions = ["Calculator", "multiply", "power", "getResult"],
values = [2, 5, 2]
Output: 100
Explanation:
new Calculator(2).multiply(5).power(2).getResult() // (2 * 5) ^ 2 = 100
class Calculator {
/**
* @param {number} value
*/
constructor(value) {
this.result = value;
}
/**
* @param {number} value
* @return {Calculator}
*/
add(value){
this.result += value;
return this;
}
/**
* @param {number} value
* @return {Calculator}
*/
subtract(value){
this.result -= value;
return this;
/**
* @param {number} value
* @return {Calculator}
*/
multiply(value) {
this.result *= value;
return this;
/**
* @param {number} value
* @return {Calculator}
*/
divide(value) {
if (value === 0) {
throw new Error("Division by zero is not allowed");
}
this.result /= value;
return this;
}
/**
* @param {number} value
* @return {Calculator}
*/
power(value) {
this.result **= value;
return this;
/**
* @return {number}
*/
getResult() {
return this.result;
}
}