Problem#
Write a function, add_subtract
, which alternately adds and subtracts curried arguments.
Examples#
Example 1#
1
2
3
Input: add_subtract( 7 )
Output: 7
Explanation: Single argument returns itself.
Example 2#
1
2
3
Input: add_subtract( 1 )( 2 )( 3 )
Output: 0
Explanation: 1 + 2 - 3 = 0 ( add first, then subtract)
Example 3#
1
2
3
Input: add_subtract(- 5 )( 10 )( 3 )( 9 )
Output: 11
Explanation: - 5 + 10 - 3 + 9 = 11 ( alternating add/ subtract starting with add)
Example 4#
1
2
3
Input: add_subtract( 10 )( 5 )
Output: 15
Explanation: 10 + 5 = 15 ( first addition)
Solution#
Method 1 - Closure with State Tracking#
Intuition#
The key insight is to use closures to maintain state between function calls. We need to track the current result and whether the next operation should be addition or subtraction. Each function call returns a new function that captures the updated state, allowing for infinite chaining while alternating operations.
Approach#
Initialize state : Start with the first argument as the initial value and set the next operation to addition
Create closure : Return a function that captures the current state (result and operation type)
Alternate operations : On each subsequent call, apply the current operation and toggle to the next
Chain functions : Each returned function maintains its own state for continued chaining
Handle termination : The function should be callable as a value when chaining ends
Code#
Cpp
Go
Java
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <functional>
class Solution {
public :
class AddSubtract {
private :
int result;
bool shouldAdd;
public :
AddSubtract(int val, bool add = true) : result(val), shouldAdd(add) {}
AddSubtract operator ()(int val) {
if (shouldAdd) {
return AddSubtract(result + val, false);
} else {
return AddSubtract(result - val, true);
}
}
operator int () const {
return result;
}
int getValue () const {
return result;
}
};
AddSubtract add_subtract (int val) {
return AddSubtract(val);
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
type AddSubtract struct {
result int
shouldAdd bool
}
func (as AddSubtract ) Call (val int ) AddSubtract {
if as .shouldAdd {
return AddSubtract {result : as .result + val , shouldAdd : false }
} else {
return AddSubtract {result : as .result - val , shouldAdd : true }
}
}
func (as AddSubtract ) Value () int {
return as .result
}
func addSubtract (val int ) AddSubtract {
return AddSubtract {result : val , shouldAdd : true }
}
// Example usage:
// result := addSubtract(1).Call(2).Call(3).Value() // returns 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Solution {
public static class AddSubtract {
private int result;
private boolean shouldAdd;
public AddSubtract (int val) {
this .result = val;
this .shouldAdd = true ;
}
private AddSubtract (int res, boolean add) {
this .result = res;
this .shouldAdd = add;
}
public AddSubtract apply (int val) {
if (shouldAdd) {
return new AddSubtract(result + val, false );
} else {
return new AddSubtract(result - val, true );
}
}
public int getValue () {
return result;
}
@Override
public String toString () {
return String.valueOf (result);
}
}
public AddSubtract add_subtract (int val) {
return new AddSubtract(val);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution :
class AddSubtract :
def __init__ (self, result: int, should_add: bool = True ):
self. result = result
self. should_add = should_add
def __call__ (self, val: int) -> 'AddSubtract' :
if self. should_add:
return AddSubtract(self. result + val, False )
else :
return AddSubtract(self. result - val, True )
def __int__ (self) -> int:
return self. result
def __str__ (self) -> str:
return str(self. result)
def __repr__ (self) -> str:
return str(self. result)
def add_subtract (self, val: int) -> AddSubtract:
return self. AddSubtract(val)
Complexity#
⏰ Time complexity: O(n)
, where n is the number of function calls. Each call performs constant time operations.
🧺 Space complexity: O(n)
for storing the chain of function closures, where each closure maintains its state.
Method 2 - Functional Approach with Lambda#
Intuition#
Instead of using classes, we can implement this using pure functions and lambda expressions. Each function call returns a new lambda that captures the current state. This approach is more functional in style and demonstrates closure behavior more explicitly.
Approach#
Create initial function : Return a lambda that captures the starting value
Chain operations : Each lambda returns another lambda with updated state
Embed state : Use closure variables to track result and operation type
Handle evaluation : Provide a way to extract the final result
Maintain immutability : Each step creates a new function rather than modifying state
Code#
Cpp
Go
Java
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <functional>
class Solution {
public :
std:: function< std:: function< int ()> (int )> add_subtract(int initial) {
return [initial](int next) -> std:: function< int ()> {
return createChain (initial, next, false); // false means next operation is subtract
};
}
private :
std:: function< std:: function< int ()> (int )> createChain(int current, int next, bool shouldAdd) {
int newResult = shouldAdd ? current + next : current + next;
return [newResult, shouldAdd](int val) -> std:: function< int ()> {
if (shouldAdd) {
return createChainStep (newResult - val, true);
} else {
return createChainStep (newResult - val, true);
}
};
}
std:: function< int ()> createChainStep(int result, bool nextAdd) {
return [result, nextAdd, this ]() -> int {
return result;
};
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
func addSubtractFunc (initial int ) func (int ) func () int {
return func (next int ) func () int {
result := initial + next
return createChain (result , false ) // false means next should subtract
}
}
func createChain (current int , shouldAdd bool ) func (int ) func () int {
return func (val int ) func () int {
var newResult int
if shouldAdd {
newResult = current + val
} else {
newResult = current - val
}
return createChain (newResult , !shouldAdd )
}
}
// Helper to get final value
func getValue (f func () int ) int {
return f ()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import java.util.function.Function;
import java.util.function.Supplier;
class Solution {
public Function< Integer, Supplier< Integer>> add_subtract (int initial) {
return next -> () -> createChain(initial + next, false ).apply (0).get ();
}
private Function< Integer, Supplier< Integer>> createChain (int current, boolean shouldAdd) {
return val -> {
int newResult = shouldAdd ? current + val : current - val;
return () -> newResult;
};
}
// Alternative implementation with better chaining
public static class FunctionalAddSubtract {
private final int value;
private final boolean shouldAdd;
public FunctionalAddSubtract (int val) {
this .value = val;
this .shouldAdd = true ;
}
private FunctionalAddSubtract (int val, boolean add) {
this .value = val;
this .shouldAdd = add;
}
public Function< Integer, FunctionalAddSubtract> chain () {
return val -> {
if (shouldAdd) {
return new FunctionalAddSubtract(value + val, false );
} else {
return new FunctionalAddSubtract(value - val, true );
}
};
}
public int getValue () {
return value;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution :
def add_subtract (self, initial: int):
def chain (current: int, should_add: bool = True ):
def inner (val: int):
if should_add:
new_result = current + val
else :
new_result = current - val
# Return a function that can continue the chain
next_chain = chain(new_result, not should_add)
next_chain. value = new_result
return next_chain
inner. value = current
return inner
return chain(initial)
# Alternative functional approach using closures
def add_subtract_functional (initial: int):
def create_chain (current: int, should_add: bool):
def apply_next (val: int):
if should_add:
new_result = current + val
else :
new_result = current - val
result_func = create_chain(new_result, not should_add)
result_func. value = new_result
return result_func
apply_next. value = current
return apply_next
return create_chain(initial, True )
Complexity#
⏰ Time complexity: O(n)
, where n is the number of chained function calls. Each function creation and call is constant time.
🧺 Space complexity: O(n)
for the chain of lambda functions, each capturing the state in its closure.
Method 3 - Iterator Pattern with State Machine#
Intuition#
We can model this as a state machine where each state represents the current result and the next operation to perform. This approach uses the iterator pattern to make the function calls feel more natural while maintaining clear state transitions.
Approach#
Define states : Create states for “add next” and “subtract next”
Implement transitions : Each function call transitions to the next state
Maintain result : Keep running total as operations are applied
Provide interface : Make the object callable while maintaining state
Handle edge cases : Ensure proper behavior for single arguments and empty chains
Code#
Cpp
Go
Java
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public :
class StateMachine {
private :
int current;
enum State { ADD_NEXT, SUBTRACT_NEXT };
State state;
public :
StateMachine(int initial) : current(initial), state(ADD_NEXT) {}
StateMachine operator ()(int val) {
StateMachine next(0 );
if (state == ADD_NEXT) {
next.current = current + val;
next.state = SUBTRACT_NEXT;
} else {
next.current = current - val;
next.state = ADD_NEXT;
}
return next;
}
operator int () const { return current; }
int getValue () const { return current; }
};
StateMachine add_subtract (int val) {
return StateMachine(val);
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
type State int
const (
AddNext State = iota
SubtractNext
)
type StateMachine struct {
current int
state State
}
func newStateMachine (initial int ) StateMachine {
return StateMachine {current : initial , state : AddNext }
}
func (sm StateMachine ) Apply (val int ) StateMachine {
switch sm .state {
case AddNext :
return StateMachine {
current : sm .current + val ,
state : SubtractNext ,
}
case SubtractNext :
return StateMachine {
current : sm .current - val ,
state : AddNext ,
}
}
return sm
}
func (sm StateMachine ) Value () int {
return sm .current
}
func addSubtractState (val int ) StateMachine {
return newStateMachine (val )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Solution {
public enum Operation { ADD_NEXT, SUBTRACT_NEXT }
public static class StateMachine {
private final int current;
private final Operation nextOp;
public StateMachine (int val) {
this .current = val;
this .nextOp = Operation.ADD_NEXT ;
}
private StateMachine (int curr, Operation op) {
this .current = curr;
this .nextOp = op;
}
public StateMachine apply (int val) {
switch (nextOp) {
case ADD_NEXT:
return new StateMachine(current + val, Operation.SUBTRACT_NEXT );
case SUBTRACT_NEXT:
return new StateMachine(current - val, Operation.ADD_NEXT );
default :
throw new IllegalStateException("Invalid operation" );
}
}
public int getValue () {
return current;
}
@Override
public String toString () {
return String.valueOf (current);
}
}
public StateMachine add_subtract (int val) {
return new StateMachine(val);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from enum import Enum
class Solution :
class Operation (Enum):
ADD_NEXT = "add"
SUBTRACT_NEXT = "subtract"
class StateMachine :
def __init__ (self, current: int, next_op: 'Solution.Operation' = None ):
self. current = current
self. next_op = next_op or Solution. Operation. ADD_NEXT
def __call__ (self, val: int) -> 'Solution.StateMachine' :
if self. next_op == Solution. Operation. ADD_NEXT:
return Solution. StateMachine(
self. current + val,
Solution. Operation. SUBTRACT_NEXT
)
else :
return Solution. StateMachine(
self. current - val,
Solution. Operation. ADD_NEXT
)
def __int__ (self) -> int:
return self. current
def __str__ (self) -> str:
return str(self. current)
def getValue (self) -> int:
return self. current
def add_subtract (self, val: int) -> StateMachine:
return self. StateMachine(val)
Complexity#
⏰ Time complexity: O(n)
, where n is the number of operations. Each state transition takes constant time.
🧺 Space complexity: O(1)
per state machine instance, as each only stores current value and next operation. Total space is O(n) for n chained calls.