Skip to content

Commit fe683a6

Browse files
committed
added benchmark and improved time
Signed-off-by: mukeshsingh.negi@infosys.com <mukesh7758negi@gmail.com>
1 parent 21966fc commit fe683a6

1 file changed

Lines changed: 93 additions & 43 deletions

File tree

‎data_structures/arrays/product_sum.py‎

Lines changed: 93 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
1616
Example Input:
1717
[5, 2, [-7, 1], 3, [6, [-13, 8], 4]]
18-
Output: 12
18+
Output: -12
1919
2020
"""
2121

22+
from timeit import timeit
23+
2224

2325
def product_sum(arr: list[int | list], depth: int) -> int:
2426
"""
@@ -92,36 +94,71 @@ def product_sum_array(array: list[int | list]) -> int:
9294
return product_sum(array, 1)
9395

9496

95-
def product_sum_iterative(arr: list[int | list | set | tuple]) -> int:
97+
def product_sum_iterative(arr: list[int | list]) -> int:
9698
"""
97-
Calculates the product sum of an array using iterative approach.
98-
99-
Logic :
100-
1. Loop until input list have nested list/tuple/set
101-
1. iterate on each item in input array
102-
2. if item is nested list/tuple/set then
103-
- multiply the nested item with it's depth and add it's elements
104-
to new array
105-
3. if item is not nested then
106-
add item to total sum
107-
4. update old array with new array and increment depth value
108-
109-
Algorithm flow example ->
110-
Step 1 --> Array - [5, 2, [-7, 1], 3, [6, [-13, 8], 4]]
111-
total sum = 0 + () = 0
112-
Step 2 --> Array - [-7, 1, -7, 1, 6, [-13, 8], 4, 6, [-13, 8], 4]
113-
total sum = 0 + (5 + 2 + 3) = 10
114-
Step 3 --> Array - [-13, 8, -13, 8, -13, 8, -13, 8, -13, 8, -13, 8]
115-
total sum = 10 + (-7 + 1 -7 + 1 + 6 + 4 + 6 + 4) = 18
116-
Step 4 --> Array - [-13, 8, -13, 8, -13, 8, -13, 8, -13, 8, -13, 8]
117-
total sum=18 +(-13 + 8 -13 + 8 -13 + 8 -13 + 8 -13 + 8 -13 + 8)= -12
99+
It Calculates the product sum of an array using iterative approach.
100+
It's similar to BFS algorithm (Breadth first search algorithm).
101+
It's won't run into stack overflow as compared to recursion approach
118102
119103
Args:
120-
array(List[Union[int, List, Set, Tuple]]): The array of integers/lists/tuple/set
104+
array(List[Union[int, List]]): The array of integers/lists
121105
122106
Returns:
123107
int: The product sum of the array.
124108
109+
Logic :
110+
1. Initialize a queue which stores the list, current
111+
depth and it's multiplication factor
112+
eg. queue -> [(arr, depth, multiplication_factor)]
113+
114+
2. Loop until queue is empty
115+
1. Pop starting element of queue
116+
2. Iterate on starting element of queue
117+
If current element is nested list
118+
- then add that into queue with updated depth
119+
and multiplication factor
120+
Else if current element is not nested
121+
- then update product sum variable by multiplying
122+
current element with multiplicaton factor
123+
124+
Algorithm flow example ->
125+
Input list - [5, 2, [-7, 1], 3, [6, [-13, 8], 4]]
126+
127+
Initialize queue - [([5, 2, [-7, 1], 3, [6, [-13, 8], 4]], 1, 1)]
128+
129+
Step 0
130+
Queue - [([5, 2, [-7, 1], 3, [6, [-13, 8], 4]], 1, 1)]
131+
top element - [5, 2, [-7, 1], 3, [6, [-13, 8], 4]]
132+
depth - 1
133+
multiplication factor - 1
134+
135+
product sum = 0 (previous) + 5 * 1 + 2 * 1 + 3 * 1 = 10
136+
-------------------------------------------------------
137+
Step 1
138+
Queue - [([-7, 1], 2, 2), ([6, [-13, 8], 4], 2, 2)]
139+
top element - [-7, 1]
140+
depth - 2
141+
multiplication factor - 2
142+
143+
product sum = 10 (previous) + (-7) * 2 + 1 * 2 = -2
144+
-------------------------------------------------------
145+
Step 2
146+
Queue - [([6, [-13, 8], 4], 2, 2)]
147+
top element - [6, [-13, 8], 4]
148+
depth - 2
149+
multiplication factor - 2
150+
151+
product sum = -2 (previous) + 6 * 2 + 4 * 2 = 18
152+
-------------------------------------------------------
153+
Step 3
154+
Queue - [([-13, 8], 3, 6)]
155+
top element - [-13, 8]
156+
depth - 3
157+
multiplication factor - 6
158+
159+
product sum = 18 (previous) + (-13) * 6 + 8 * 6 = -12
160+
-------------------------------------------------------
161+
125162
Examples:
126163
>>> product_sum_iterative([1, 2, 3])
127164
6
@@ -135,36 +172,49 @@ def product_sum_iterative(arr: list[int | list | set | tuple]) -> int:
135172
1.5
136173
>>> product_sum_iterative([1, -2])
137174
-1
138-
175+
>>> product_sum_iterative([5, 2, [-7, 1], 3, [6, [-13, 8], 4]])
176+
-12
139177
"""
140178

141-
# depth of the nested list/tuple/set
142-
next_depth = 2
143-
144-
# flag to check whether list has nested items or not
145-
nested_list_check = True
179+
# Initialize queue with depth and multiplication factor
180+
queue = [(arr, 1, 1)]
146181

147-
total_sum = 0
182+
product_sum = 0
148183

149-
while nested_list_check:
150-
# list to store new items
151-
new_arr = []
152-
nested_list_check = False
184+
while queue:
185+
starting_element, depth, multiplication_factor = queue.pop(0)
153186

154-
for item in arr:
155-
if isinstance(item, list | tuple | set):
156-
new_arr.extend(list(item) * next_depth)
157-
nested_list_check = True
187+
for element in starting_element:
188+
if isinstance(element, list):
189+
queue.append((element, depth + 1, multiplication_factor * (depth + 1)))
158190
else:
159-
total_sum += item
191+
product_sum += element * multiplication_factor
192+
193+
return product_sum
194+
195+
196+
def benchmark() -> None:
197+
"""
198+
Benchmark code comparing different version.
199+
"""
200+
201+
setup = "from __main__ import product_sum_array, product_sum_iterative"
160202

161-
arr = new_arr
162-
next_depth += 1
203+
print(
204+
timeit("product_sum_array([5, 2, [-7, 1], 3, [6, [-13, 8], 4]])", setup=setup)
205+
)
206+
# 1.1448657000437379
163207

164-
return total_sum
208+
print(
209+
timeit(
210+
"product_sum_iterative([5, 2, [-7, 1], 3, [6, [-13, 8], 4]])", setup=setup
211+
)
212+
)
213+
# 1.6824490998405963
165214

166215

167216
if __name__ == "__main__":
168217
import doctest
169218

170219
doctest.testmod()
220+
benchmark()

0 commit comments

Comments
 (0)