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.
Your Calculator class should have the following methods:
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-5 of the actual result are considered correct.
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
Example 3:
Input: actions = ["Calculator", "divide", "getResult"], values = [20, 0] Output: "Division by zero is not allowed" Explanation: new Calculator(20).divide(0).getResult() // 20 / 0 The error should be thrown because we cannot divide by zero.
Constraints:
actions is a valid JSON array of stringsvalues is a valid JSON array of numbers2 <= actions.length <= 2 * 1041 <= values.length <= 2 * 104 - 1actions[i] is one of "Calculator", "add", "subtract", "multiply", "divide", "power", and "getResult"The key idea behind Calculator with Method Chaining is implementing a class that maintains an internal numeric state and allows operations to be chained together. Each arithmetic method (such as add, subtract, multiply, or divide) updates the internal value and then returns the current object using this. Returning the same instance enables multiple method calls to be chained in a single expression.
While designing the calculator, store the current result in a class variable initialized in the constructor. Every operation modifies this stored value. For robustness, consider handling edge cases such as division by zero, which may require throwing an error or handling it according to the problem statement.
This approach focuses on clean object-oriented design and the fluent interface pattern. Since each operation performs a constant-time arithmetic update on a stored value, the overall time and space complexity remain minimal.
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Class-based calculator with method chaining | O(1) per operation | O(1) |
Greg Hogg
In this approach, we will design a Calculator class with a constructor that initializes the result. Each operation method will modify the object's state and return the Calculator object itself to allow method chaining. The method for division needs to handle division by zero gracefully by throwing an appropriate exception.
Time Complexity: O(1) for each operation since they all perform a constant amount of work.
Space Complexity: O(1) since we use only a fixed amount of space irrespective of input size.
1class Calculator:
2 def __init__(self, initial_value):
3 self.result = initial_value
4
5 def add(self, value):
6 self.result += value
7 return self
8
9 def subtract(self, value):
10 self.result -= value
11 return self
12
13 def multiply(self, value):
14 self.result *= value
15 return self
16
17 def divide(self, value):
18 if value == 0:
19 raise ValueError("Division by zero is not allowed")
20 self.result /= value
21 return self
22
23 def power(self, value):
24 self.result **= value
25 return self
26
27 def getResult(self):
28 return self.resultIn the Python solution, each method modifies self.result, a class attribute, and returns self to allow method chaining. The divide method checks for division by zero and raises a ValueError if encountered. The getResult() method returns the current result.
This approach emphasizes clear error management alongside method chaining. Each mathematical function adjusts the internal result and returns the instance for seamless operation chaining. Special attention is paid to division, where an exception is thrown in case of dividing by zero, ensuring the program handles this gracefully.
Time Complexity: O(1) for each operation; each involves direct arithmetic with a constant time overhead.
Space Complexity: O(1) due to constant space usage regardless of input size.
1class Calculator {
2 constructor(
Watch expert explanations and walkthroughs
Jot down your thoughts, approach, and key learnings
Problems like this are sometimes used to test object-oriented design and understanding of fluent interfaces. While not always asked directly, similar design-based questions can appear in interviews at large tech companies.
Method chaining allows multiple operations to be written in a single readable expression. It works by returning the current object instance after each method call, enabling the next method to be called immediately.
No complex data structure is required for this problem. A simple class with a single variable to store the current value is sufficient, as each operation directly updates that value.
The optimal approach is to design a class that stores the current result and returns the same object after each operation. By returning 'this' from every arithmetic method, you enable method chaining while maintaining a single internal state.
In the JavaScript implementation, each operation method updates the result attribute and returns the current instance to enable method chaining. The divide method checks for zero to prevent division by zero, throwing an Error as appropriate. The method getResult retrieves the current value of result.