2726. Calculator with Method Chaining
Problem Description
The problem requires designing a Calculator
class that supports basic mathematical operations like addition, subtraction, multiplication, division, and exponentiation. The class is not only asked to perform these operations but to do so in a way that allows for method chaining, which means calling multiple methods in a single statement. When an instance of the Calculator
class is created, it receives an initial number that is used as its starting result
. The following methods need to be implemented:
add(value)
- Adds a number to the current result and returns theCalculator
instance for chaining.subtract(value)
- Subtracts a number from the current result and returns theCalculator
instance for chaining.multiply(value)
- Multiplies the current result by a number and returns theCalculator
instance for chaining.divide(value)
- Divides the current result by a number and returns theCalculator
instance for chaining, with an error for division by zero.power(value)
- Raises the current result to the power of a number and returns theCalculator
instance for chaining.getResult()
- Returns the current result.
The problem also specifies that results within a tolerance of 10^-5
are considered correct, indicating that some degree of imprecision from floating-point arithmetic is acceptable.
Intuition
To solve this problem, the main idea is to structure the Calculator
class with a private property to hold the current result
. Each mathematical operation will be a method that performs the appropriate calculation on this result
and then returns the Calculator
object to allow method chaining.
The intuition behind each method is straightforward:
add()
: Updateresult
by adding the provided value.subtract()
: Updateresult
by subtracting the provided value.multiply()
: Updateresult
by multiplying it by the provided value.divide()
: Check for division by zero, throw an error if it occurs, otherwise updateresult
by dividing it by the provided value.power()
: Updateresult
by raising it to the power of the provided value using the exponentiation operator.getResult()
: Simply return the currentresult
.
Overall, the principle is to encapsulate the state of the calculator in each instance and use method chaining to make the calculator more expressive and convenient to use.
Solution Approach
The implementation of the Calculator
class is quite straightforward. The class uses an instance variable x
to store the current result
. Each method performs a simple arithmetic operation and returns the instance (this
) for method chaining. Here's the breakdown of the solution:
-
Constructor: The constructor initializes the
Calculator
with a starting value. This value is stored in the private variablex
.constructor(value: number) { this.x = value; }
-
Addition: The
add
method takes avalue
and adds it to thex
. The method then returns theCalculator
instance for further chaining.add(value: number): Calculator { this.x += value; return this; }
-
Subtraction: The
subtract
function is similar toadd
, but it subtracts the given value fromx
.subtract(value: number): Calculator { this.x -= value; return this; }
-
Multiplication: The
multiply
method multipliesx
by the specifiedvalue
.multiply(value: number): Calculator { this.x *= value; return this; }
-
Division: In the
divide
method, the class first checks if thevalue
is zero, and if so, throws an exception since division by zero is undefined. Otherwise, it dividesx
by thevalue
.divide(value: number): Calculator { if (value === 0) { throw new Error('Division by zero is not allowed'); } this.x /= value; return this; }
-
Exponentiation: The
power
method raisesx
to the power of thevalue
provided.power(value: number): Calculator { this.x **= value; return this; }
-
Get Result: Finally, the
getResult
method simply returns the variablex
.getResult(): number { return this.x; }
No complex algorithms or data structures are needed; the solution relies on the basic arithmetic operators provided by TypeScript/javascript. The design pattern used is method chaining, which is commonly used to create more readable and expressive code. This pattern is also known as the fluent interface pattern. The class methods perform their operation and then return the object itself, which allows these method calls to be connected in a single chain.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's create an example to illustrate how to use the Calculator
class and demonstrate the solution approach mentioned above.
Suppose we want to perform a sequence of operations starting with the number 10. We would like to add 5, subtract 2, multiply by 3, divide by 4, and then raise to the power of 2. We aim to achieve this using method chaining provided by our Calculator
class.
First, we create a new instance of the Calculator
class and initialize it with the number 10.
let calc = new Calculator(10);
Now we can start chaining our operations. The first operation is to add 5 to our initial number, which we achieve by calling the add
method.
calc.add(5); // Starting with 10, we now have 15
Next, we chain the subtract
method to subtract 2 from our current result.
calc.subtract(2); // From 15, subtracting 2 gives us 13
We continue with the multiply
method to multiply our result by 3.
calc.multiply(3); // Multiplying 13 by 3 gets us 39
The sequence then calls for division by 4, which we apply using the divide
method.
calc.divide(4); // Dividing 39 by 4 gives us 9.75
Finally, we chain the power
method to raise our result to the power of 2.
calc.power(2); // 9.75 raised to the power of 2 is approximately 95.0625
After performing all the chained operations, we use the getResult
method to obtain and print out the final result.
let result = calc.getResult(); // Retrieves the final result, which is approximately 95.0625
console.log(result); // This will output 95.0625
Putting all the chained operations together, we can express the entire sequence in one line of code as follows:
let finalResult = new Calculator(10).add(5).subtract(2).multiply(3).divide(4).power(2).getResult();
console.log(finalResult); // Outputs the same result: 95.0625
The example above demonstrates how constructor initialization, method chaining, and straightforward arithmetic operations are implemented and used in the Calculator
class. Each method modifies the internal state of the Calculator
object and returns the object itself, making the sequence of operations concise and readable. This implementation leverages the principle of fluent interfaces for an expressive code style.
Solution Implementation
1# Define a variable for storing current value of calculations
2current_value = 0
3
4def initialize_calculator(value):
5 """
6 Initializes the calculator with a specific value.
7
8 :param value: The initial value to set the calculator to.
9 """
10 global current_value
11 current_value = value
12
13def add(value):
14 """
15 Adds a given value to the current value.
16
17 :param value: The value to be added.
18 """
19 global current_value
20 current_value += value
21
22def subtract(value):
23 """
24 Subtracts a given value from the current value.
25
26 :param value: The value to be subtracted.
27 """
28 global current_value
29 current_value -= value
30
31def multiply(value):
32 """
33 Multiplies the current value by a given value.
34
35 :param value: The value to multiply by.
36 """
37 global current_value
38 current_value *= value
39
40def divide(value):
41 """
42 Divides the current value by a given value.
43 Throws an error if division by zero is attempted.
44
45 :param value: The value to divide by.
46 """
47 global current_value
48 if value == 0:
49 raise ValueError('Division by zero is not allowed')
50 current_value /= value
51
52def power(value):
53 """
54 Raises the current value to the power of a given value.
55
56 :param value: The exponent to raise the current value to.
57 """
58 global current_value
59 current_value **= value
60
61def get_result():
62 """
63 Retrieves the current result of the calculator's operations.
64
65 :return: The current value.
66 """
67 return current_value
68
69# Example usage:
70initialize_calculator(10) # Set the current value to 10
71add(5) # Add 5 to the current value
72subtract(3) # Subtract 3 from the current value
73multiply(2) # Multiply the current value by 2
74divide(4) # Divide the current value by 4
75power(2) # Raise the current value to the power of 2
76print(get_result()) # Output the current result
77
1public class Calculator {
2
3 // Variable for storing current value of calculations
4 private double currentValue;
5
6 /**
7 * Initializes the calculator with a specific value.
8 *
9 * @param value The initial value to set the calculator to.
10 */
11 public void initializeCalculator(double value) {
12 this.currentValue = value;
13 }
14
15 /**
16 * Adds a given value to the current value.
17 *
18 * @param value The value to be added.
19 */
20 public void add(double value) {
21 this.currentValue += value;
22 }
23
24 /**
25 * Subtracts a given value from the current value.
26 *
27 * @param value The value to be subtracted.
28 */
29 public void subtract(double value) {
30 this.currentValue -= value;
31 }
32
33 /**
34 * Multiplies the current value by a given value.
35 *
36 * @param value The value to multiply by.
37 */
38 public void multiply(double value) {
39 this.currentValue *= value;
40 }
41
42 /**
43 * Divides the current value by a given value.
44 * Throws an IllegalArgumentException if division by zero is attempted.
45 *
46 * @param value The value to divide by.
47 */
48 public void divide(double value) {
49 if (value == 0) {
50 throw new IllegalArgumentException("Division by zero is not allowed");
51 }
52 this.currentValue /= value;
53 }
54
55 /**
56 * Raises the current value to the power of a given value.
57 *
58 * @param value The exponent to raise the current value to.
59 */
60 public void power(double value) {
61 this.currentValue = Math.pow(this.currentValue, value);
62 }
63
64 /**
65 * Retrieves the current result of the calculator's operations.
66 *
67 * @return The current value.
68 */
69 public double getResult() {
70 return this.currentValue;
71 }
72
73 // Example usage
74 public static void main(String[] args) {
75 Calculator calc = new Calculator(); // Create a new Calculator instance.
76
77 calc.initializeCalculator(10); // Set the current value to 10.
78 calc.add(5); // Add 5 to the current value.
79 calc.subtract(3); // Subtract 3 from the current value.
80 calc.multiply(2); // Multiply the current value by 2.
81 calc.divide(4); // Divide the current value by 4.
82 calc.power(2); // Raise the current value to the power of 2.
83
84 System.out.println(calc.getResult()); // Outputs the current result.
85 }
86}
87
1#include <iostream>
2#include <stdexcept>
3
4// Declare a variable for storing the current value of calculations.
5double currentValue = 0;
6
7/**
8 * Initializes the calculator with a specific value.
9 * @param value The initial value to set the calculator to.
10 */
11void initializeCalculator(double value) {
12 currentValue = value;
13}
14
15/**
16 * Adds a given value to the current value.
17 * @param value The value to be added.
18 */
19void add(double value) {
20 currentValue += value;
21}
22
23/**
24 * Subtracts a given value from the current value.
25 * @param value The value to be subtracted.
26 */
27void subtract(double value) {
28 currentValue -= value;
29}
30
31/**
32 * Multiplies the current value by a given value.
33 * @param value The value to multiply by.
34 */
35void multiply(double value) {
36 currentValue *= value;
37}
38
39/**
40 * Divides the current value by a given value.
41 * Throws an error if division by zero is attempted.
42 * @param value The value to divide by.
43 */
44void divide(double value) {
45 if (value == 0) {
46 throw std::invalid_argument("Division by zero is not allowed.");
47 }
48 currentValue /= value;
49}
50
51/**
52 * Raises the current value to the power of a given value.
53 * @param value The exponent to raise the current value to.
54 */
55void power(double value) {
56 currentValue = std::pow(currentValue, value);
57}
58
59/**
60 * Retrieves the current result of the calculator's operations.
61 * @return The current value.
62 */
63double getResult() {
64 return currentValue;
65}
66
67// Function to demonstrate example usage of the calculator functions.
68void exampleUsage() {
69 initializeCalculator(10); // Set the current value to 10.
70 add(5); // Add 5 to the current value.
71 subtract(3); // Subtract 3 from the current value.
72 multiply(2); // Multiply the current value by 2.
73 divide(4); // Divide the current value by 4.
74 power(2); // Raises the current value to the power of 2.
75 std::cout << getResult(); // Outputs the current result.
76}
77
78int main() {
79 // Call the example usage function to demonstrate the calculator's functionality.
80 exampleUsage();
81 return 0;
82}
83
1// Define a variable for storing current value of calculations
2let currentValue: number = 0;
3
4/**
5 * Initializes the calculator with a specific value.
6 * @param {number} value - The initial value to set the calculator to.
7 */
8function initializeCalculator(value: number): void {
9 currentValue = value;
10}
11
12/**
13 * Adds a given value to the current value.
14 * @param {number} value - The value to be added.
15 * @returns The calculator object for method chaining.
16 */
17function add(value: number): void {
18 currentValue += value;
19}
20
21/**
22 * Subtracts a given value from the current value.
23 * @param {number} value - The value to be subtracted.
24 * @returns The calculator object for method chaining.
25 */
26function subtract(value: number): void {
27 currentValue -= value;
28}
29
30/**
31 * Multiplies the current value by a given value.
32 * @param {number} value - The value to multiply by.
33 * @returns The calculator object for method chaining.
34 */
35function multiply(value: number): void {
36 currentValue *= value;
37}
38
39/**
40 * Divides the current value by a given value.
41 * Throws an error if division by zero is attempted.
42 * @param {number} value - The value to divide by.
43 * @returns The calculator object for method chaining.
44 */
45function divide(value: number): void {
46 if (value === 0) {
47 throw new Error('Division by zero is not allowed');
48 }
49 currentValue /= value;
50}
51
52/**
53 * Raises the current value to the power of a given value.
54 * @param {number} value - The exponent to raise the current value to.
55 * @returns The calculator object for method chaining.
56 */
57function power(value: number): void {
58 currentValue **= value;
59}
60
61/**
62 * Retrieves the current result of the calculator's operations.
63 * @returns The current value.
64 */
65function getResult(): number {
66 return currentValue;
67}
68
69// Example usage:
70initializeCalculator(10); // Set the current value to 10.
71add(5); // Add 5 to the current value.
72subtract(3); // Subtract 3 from the current value.
73multiply(2); // Multiply the current value by 2.
74divide(4); // Divide the current value by 4.
75power(2); // Raises the current value to the power of 2.
76console.log(getResult()); // Outputs the current result.
77
Time and Space Complexity
The time complexity of the Calculator class methods is O(1)
for the add
, subtract
, multiply
, divide
, and power
methods, because each of these operations consists of a single arithmetic operation that is independent of the size of the input.
The space complexity of the Calculator class is also O(1)
as it only stores a single number regardless of the operations performed.
Which algorithm is best for finding the shortest distance between two points in an unweighted graph?
Recommended Readings
LeetCode Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way we
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!