Problem: Let us consider an array with real values (positive and negative) Determine a subarray containing elements with alternating signs (positive followed negative, negative followed by positive) for which the sum of the absolute value of the elements is maximal.
After running the code with this list it doesn’t give me the right output
the output is [6, -3, 7, -5, 13, 12, 8, -9]
but it should be [6, -3, 7, -5, 13, -9, 8]
JavaScript
x
34
34
1
a_list = [2, 6, -3, 7, -2, -5, 10, 13, 13, 13, 13, 12, 12, 12, 12, 12, 8, 8, 8, 8, 8, 8, -9, 8, -9, -9, -9, -9, -9, -9, -9, -9, 12, 12, 12, 12, 12] # [6, -3, 7, -5, 12]
2
sum_list = []
3
i=0
4
while i <len(a_list)-1:
5
if (a_list[i] < 0 and a_list[i+1] > 0):
6
if a_list[i] in sum_list:
7
pass
8
else:
9
if sum_list[-1]<0:
10
pass
11
else:
12
sum_list.append(a_list[i])
13
if (a_list[i] > 0 and a_list[i+1] < 0):
14
if a_list[i] in sum_list:
15
pass
16
else:
17
if sum_list[-1]>0:
18
pass
19
else:
20
sum_list.append(a_list[i])
21
else:
22
if a_list[i]>0 and a_list[i+1]>0:
23
if max(a_list[i],a_list[i+1]) in sum_list:
24
pass
25
else:
26
sum_list.append(max(a_list[i],a_list[i+1]))
27
if a_list[i]<0 and a_list[i+1]<0:
28
if min(a_list[i],a_list[i+1]) in sum_list:
29
pass
30
else:
31
sum_list.append(min(a_list[i], a_list[i + 1]))
32
i=i+1
33
print(sum_list)```
34
Advertisement
Answer
Update: the code is not correct in general, I’m at it …
Update: corrected version see below
This gives the expected result (with a few inline comments):
JavaScript
1
48
48
1
#https://stackoverflow.com/questions/65673470/
2
3
# test lists for a few edge cases
4
list_1 = []
5
list_2 = [0]
6
list_3 = [0, 0]
7
list_4 = [0, 0, 0]
8
list_5 = [-2, 4, -2, 4]
9
list_6 = [2, -4, 2, -4]
10
11
t_list = [ 2, 6
12
, -3
13
, 7
14
, -2, -5
15
, 10, 13, 13, 13, 13, 12, 12, 12, 12, 12, 8, 8, 8, 8, 8, 8
16
, -9
17
, 8
18
, -9, -9, -9, -9, -9, -9, -9, -9
19
, 12, 12, 12, 12, 12
20
] # expected result: [6, -3, 7, -5, 13, -9, 8]
21
22
all_lists = [list_1, list_2, list_3, list_4, list_5, list_6, t_list]
23
24
def sign_differs(n1, n2):
25
'''return True if n1 and n2 have different signs.'''
26
return n1 < 0 and n2 >= 0 or n1 >= 0 and n2 < 0
27
28
for a_list in all_lists:
29
print(f'a_list: {a_list}')
30
31
sum_list = []
32
prev_idx = 0
33
for idx in range(1, len(a_list)):
34
n1, n2 = a_list[idx-1], a_list[idx]
35
if n1 in sum_list:
36
continue
37
if sign_differs(n1, n2): # +/- or -/+ detected
38
if a_list[prev_idx] >= 0:
39
max_abs = max(a_list[prev_idx:idx]) # largest positive
40
else:
41
max_abs = min(a_list[prev_idx:idx]) # smallest negative
42
43
if not max_abs in sum_list:
44
sum_list.append(max_abs)
45
prev_idx = idx
46
47
print(f'sum_list: {sum_list}n')
48
Output including a few test cases:
JavaScript
1
21
21
1
a_list: []
2
sum_list: []
3
4
a_list: [0]
5
sum_list: []
6
7
a_list: [0, 0]
8
sum_list: []
9
10
a_list: [0, 0, 0]
11
sum_list: []
12
13
a_list: [-2, 4, -2, 4]
14
sum_list: [-2, 4]
15
16
a_list: [2, -4, 2, -4]
17
sum_list: [2, -4]
18
19
a_list: [2, 6, -3, 7, -2, -5, 10, 13, 13, 13, 13, 12, 12, 12, 12, 12, 8, 8, 8, 8, 8, 8, -9, 8, -9, -9, -9, -9, -9, -9, -9, -9, 12, 12, 12, 12, 12]
20
sum_list: [6, -3, 7, -5, 13, -9, 8]
21
Corrected version:
JavaScript
1
77
77
1
#https://stackoverflow.com/questions/65673470/
2
3
# test lists for a few (edge) cases
4
list_1 = []
5
list_2 = [0]
6
list_3 = [0, 0]
7
list_4 = [0, 0, 0]
8
list_5 = [-2, 4, -2, 4]
9
list_6 = [2, -1, 2, -2, -3, -4, 3]
10
list_7 = [-99, 2, -1, 3, -1, 4, 5, -3, -3, 4, -1, -3, -4, -5, 2, 3, -5, 6, 4, 7]
11
12
t_list = [ 2, 6
13
, -3
14
, 7
15
, -2, -5
16
, 10, 13, 13, 13, 12, 12, 12, 8, 8, 8
17
, -9
18
, 8
19
, -9, -9, -9
20
, 12, 12, 12
21
] # expexted result: [6, -3, 7, -5, 13, -9, 8]
22
23
all_lists = [list_1, list_2, list_3, list_4, list_5, list_6, list_7, t_list]
24
25
def alternating_nums(a_list):
26
sum_list = []
27
if not a_list:
28
return sum_list
29
number = a_list[0]
30
sum_list = [number]
31
srch_neg = number >= 0 # look for next pos./neg. number
32
other_ok = True
33
34
for number in a_list:
35
if srch_neg: # searching for a neg. number
36
if number >= 0:
37
if number in sum_list:
38
continue
39
if number <= sum_list[-1]:
40
continue
41
if not other_ok:
42
continue
43
sum_list[-1] = number # found a "better" one
44
continue
45
if number < 0:
46
if number in sum_list:
47
other_ok = False
48
continue
49
sum_list.append(number)
50
srch_neg = False # now searching for a pos. number
51
other_ok = True # a consecutive smaller neg. will be ok, too
52
continue
53
else: # searching for a pos. number
54
if number < 0:
55
if number in sum_list:
56
continue
57
if number >= sum_list[-1]:
58
continue
59
if not other_ok:
60
continue
61
sum_list[-1] = number # found a "better" one
62
continue
63
if number >= 0:
64
if number in sum_list:
65
other_ok = False
66
continue
67
sum_list.append(number)
68
srch_neg = True # now searching for a neg. number
69
other_ok = True # a consecutive larger pos. will be ok, too
70
continue
71
return sum_list
72
73
for a_list in all_lists:
74
print(a_list)
75
sum_list = alternating_nums(a_list)
76
print(sum_list, 'n')
77