1515
1616Example 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
2325def 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
167216if __name__ == "__main__" :
168217 import doctest
169218
170219 doctest .testmod ()
220+ benchmark ()
0 commit comments