Skip to content

Commit 6e255f6

Browse files
committed
Fix minimum partition for negative numbers
1 parent 6c04620 commit 6e255f6

1 file changed

Lines changed: 12 additions & 34 deletions

File tree

dynamic_programming/minimum_partition.py

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
Partition a set into two subsets such that the difference of subset sums is minimum
33
"""
44

5+
from collections.abc import Iterable
56

6-
def find_min(numbers: list[int]) -> int:
7+
8+
def find_min(numbers: Iterable[int]) -> int:
79
"""
810
>>> find_min([1, 2, 3, 4, 5])
911
1
@@ -21,8 +23,6 @@ def find_min(numbers: list[int]) -> int:
2123
0
2224
>>> find_min([-1, -5, 5, 1])
2325
0
24-
>>> find_min([-1, -5, 5, 1])
25-
0
2626
>>> find_min([9, 9, 9, 9, 9])
2727
9
2828
>>> find_min([1, 5, 10, 3])
@@ -32,42 +32,20 @@ def find_min(numbers: list[int]) -> int:
3232
>>> find_min(range(10, 0, -1))
3333
1
3434
>>> find_min([-1])
35-
Traceback (most recent call last):
36-
--
37-
IndexError: list assignment index out of range
35+
1
3836
>>> find_min([0, 0, 0, 1, 2, -4])
39-
Traceback (most recent call last):
40-
...
41-
IndexError: list assignment index out of range
37+
1
4238
>>> find_min([-1, -5, -10, -3])
43-
Traceback (most recent call last):
44-
...
45-
IndexError: list assignment index out of range
39+
1
4640
"""
47-
n = len(numbers)
48-
s = sum(numbers)
49-
50-
dp = [[False for x in range(s + 1)] for y in range(n + 1)]
51-
52-
for i in range(n + 1):
53-
dp[i][0] = True
54-
55-
for i in range(1, s + 1):
56-
dp[0][i] = False
57-
58-
for i in range(1, n + 1):
59-
for j in range(1, s + 1):
60-
dp[i][j] = dp[i - 1][j]
61-
62-
if numbers[i - 1] <= j:
63-
dp[i][j] = dp[i][j] or dp[i - 1][j - numbers[i - 1]]
41+
total_sum = 0
42+
reachable_sums = {0}
6443

65-
for j in range(int(s / 2), -1, -1):
66-
if dp[n][j] is True:
67-
diff = s - 2 * j
68-
break
44+
for number in numbers:
45+
total_sum += number
46+
reachable_sums |= {reachable_sum + number for reachable_sum in reachable_sums}
6947

70-
return diff
48+
return min(abs(total_sum - 2 * reachable_sum) for reachable_sum in reachable_sums)
7149

7250

7351
if __name__ == "__main__":

0 commit comments

Comments
 (0)