master > master: code - refactoring + counting für maxsubsum überarbeitet
This commit is contained in:
		
							parent
							
								
									82962e376d
								
							
						
					
					
						commit
						ecbf274be6
					
				| @ -11,4 +11,4 @@ from code.algorithms.search.interpol import InterpolationSearch; | ||||
| from code.algorithms.search.jump import JumpSearchLinear; | ||||
| from code.algorithms.search.jump import JumpSearchExponentiell; | ||||
| from code.algorithms.search.ith_smallest import FindIthSmallest; | ||||
| from code.algorithms.search.ith_smallest_dc import FindIthSmallestDC; | ||||
| from code.algorithms.search.ith_smallest import FindIthSmallestDC; | ||||
|  | ||||
| @ -63,3 +63,35 @@ def FindIthSmallest(L: List[int], i: int) -> int: | ||||
|         logDebug('Entfernte Minimum: {value}.'.format(value = minValue)); | ||||
|         i = i - 1; | ||||
|         return FindIthSmallest(L=L[:index] + L[(index+1):], i=i); | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # ALGORITHM jump search (D & C) | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| @algorithmInfos(name='Auswahlproblem (i. kleinstes Element, D & C)', outputnames='value', checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks) | ||||
| def FindIthSmallestDC(L: List[int], i: int) -> int: | ||||
|     ''' | ||||
|     Inputs: L = Liste von Zahlen, i = Ordinalzahl | ||||
| 
 | ||||
|     Annahmen: | ||||
| 
 | ||||
|     - L enthält keine Duplikate. | ||||
|     - L enthält mindestens i Elemente. | ||||
| 
 | ||||
|     Outputs: Wert des i. kleinste Element in L. | ||||
|              Beachte 1.kleinstes <==> Minimum. | ||||
|     ''' | ||||
|     AddToCounter(); | ||||
|     p = L[len(L)-1]; # NOTE: Pivotelement kann beliebig gewählt werden | ||||
|     Ll = [ x for x in L if x < p ]; | ||||
|     Lr = [ x for x in L if x > p ]; | ||||
|     if len(Ll) == i - 1: | ||||
|         logDebug('Es gibt   i-1 Elemente vor p={p}. ==> i. kleinste Element = p'.format(p=p)); | ||||
|         return p; | ||||
|     elif len(Ll) >= i: | ||||
|         logDebug('Es gibt  >= i Elemente vor p={p}. ==> Suche in linker Hälfte!'.format(p=p)); | ||||
|         return FindIthSmallestDC(L=Ll, i=i); | ||||
|     else: | ||||
|         i = i - (len(Ll) + 1) | ||||
|         logDebug('Es gibt < i-1 Elemente vor p={p}. ==> Suche in rechter Hälfte!'.format(p=p)); | ||||
|         return FindIthSmallestDC(L=Lr, i=i); | ||||
|  | ||||
| @ -1,65 +0,0 @@ | ||||
| #!/usr/bin/env python3 | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # IMPORTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| from local.maths import *; | ||||
| from local.typing import *; | ||||
| 
 | ||||
| from code.core.log import *; | ||||
| from code.algorithms.search.sequential import SequentialSearch; | ||||
| from code.algorithms.methods import *; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # GLOBAL VARIABLES/CONSTANTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # CHECKS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| def preChecks(L: List[int], i: int, **_): | ||||
|     assert 1 <= i and i <= len(L), 'Der Wert von i muss zw. {lb} und {ub} liegen.'.format(lb = 1, ub = len(L)); | ||||
|     assert sorted(L) == sorted(list(set(L))), 'Ungültiger Input: L darf keine Duplikate enthalten!'; | ||||
|     return; | ||||
| 
 | ||||
| def postChecks(L: List[int], i: int, value: int, **_): | ||||
|     L_ = sorted(L); | ||||
|     assert L_[i-1] == value, 'Der Algorithmus hat versagt.'; | ||||
|     return; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # ALGORITHM jump search | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| @algorithmInfos(name='Auswahlproblem (i. kleinstes Element, D & C)', outputnames='value', checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks) | ||||
| def FindIthSmallestDC(L: List[int], i: int) -> int: | ||||
|     ''' | ||||
|     Inputs: L = Liste von Zahlen, i = Ordinalzahl | ||||
| 
 | ||||
|     Annahmen: | ||||
| 
 | ||||
|     - L enthält keine Duplikate. | ||||
|     - L enthält mindestens i Elemente. | ||||
| 
 | ||||
|     Outputs: Wert des i. kleinste Element in L. | ||||
|              Beachte 1.kleinstes <==> Minimum. | ||||
|     ''' | ||||
|     AddToCounter(); | ||||
|     p = L[len(L)-1]; # NOTE: Pivotelement kann beliebig gewählt werden | ||||
|     Ll = [ x for x in L if x < p ]; | ||||
|     Lr = [ x for x in L if x > p ]; | ||||
|     if len(Ll) == i - 1: | ||||
|         logDebug('Es gibt genau i-1 Elemente vorm Pivotelment, p. Also ist p das i. kleinste Element.'); | ||||
|         return p; | ||||
|     elif len(Ll) >= i: | ||||
|         logDebug('Es gibt mindestens i Elemente vorm Pivotelement, p. Suche wird in linker Hälfte fortgesetzt.'); | ||||
|         return FindIthSmallestDC(L=Ll, i=i); | ||||
|     else: | ||||
|         i = i - (len(Ll) + 1) | ||||
|         logDebug('Es gibt weniger als i-1 Elemente vorm Pivotelement, p. Suche wird in rechte Hälfte nach {i}. kleinstem Element fortgesetzt.'.format(i=i)); | ||||
|         return FindIthSmallestDC(L=Lr, i=i); | ||||
| @ -6,4 +6,4 @@ | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| from code.algorithms.sum.maxsubsum import MaxSubSum; | ||||
| from code.algorithms.sum.maxsubsum_dc import MaxSubSumDC; | ||||
| from code.algorithms.sum.maxsubsum import MaxSubSumDC; | ||||
|  | ||||
| @ -43,17 +43,117 @@ def MaxSubSum(L: List[float]) -> Tuple[float, int, int]: | ||||
|     ''' | ||||
|     maxSum: float = 0; | ||||
|     u: int = 0; | ||||
|     v: int = 0; | ||||
|     v: int = -1; | ||||
|     for i in range(len(L)): | ||||
|         for j in range(i+1, len(L)): | ||||
|             thisSum = 0; | ||||
|             # NOTE: Schleibe über Indexes von von i bis j | ||||
|             for k in range(i, j+1): | ||||
|                 AddToCounter(); | ||||
|                 thisSum += L[k] | ||||
|             if thisSum > maxSum: | ||||
|                 logDebug('max Teilsumme aktualisiert: Summe L[i] von i={i} bis {j} = {value}'.format( | ||||
|                     i = i, j = j, value = thisSum | ||||
|                 )); | ||||
|                 maxSum, u, v = thisSum, i, j; | ||||
|         ## Bestimme maximale Teilsumme der linken Rände der Liste ab Index i: | ||||
|         maxSum_, _, k = lRandSum(L[i:]); | ||||
|         if maxSum_ > maxSum: | ||||
|             k += i; # NOTE: muss wegen Offset kompensieren | ||||
|             maxSum, u, v = maxSum_, i, k; | ||||
|             logDebug('max Teilsumme aktualisiert: Summe L[i] von i={u} .. {v} = {value}'.format(u = u, v = v, value = maxSum)); | ||||
|     return maxSum, u, v; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # ALGORITHM max sub sum (D & C) | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| @algorithmInfos(name='MaxSubSum (Maximale Teilsumme mit D & C)', outputnames=('maxSum', 'index_from', 'index_to'), checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks) | ||||
| def MaxSubSumDC(L: List[float]) -> Tuple[float, int, int]: | ||||
|     ''' | ||||
|     Inputs:  L = Liste von Zahlen | ||||
|     Outputs: | ||||
|     - maxSum = Wert der maximalen Summe einer Teilliste aufeinanderfolgender Elemente | ||||
|     - u, v = Indexes so dass die Teilliste [L[u], L[u+1], ..., L[v]] die maximale Summe aufweist | ||||
|     ''' | ||||
|     maxSum = 0; | ||||
|     u = 0; | ||||
|     v = -1; | ||||
|     if len(L) == 1: | ||||
|         ## wenn Liste aus 1 Element besteht, nicht teilen: | ||||
|         if L[0] > maxSum: | ||||
|             v = 0; | ||||
|             maxSum = L[0]; | ||||
|     else: | ||||
|         u = math.ceil(len(L)/2); | ||||
|         Ll = L[:u]; | ||||
|         Lr = L[u:]; | ||||
|         ## berechnet maximale Teilsumme der linken Hälfte: | ||||
|         maxSum1, u1, v1 = MaxSubSumDC(L=Ll); | ||||
|         ## berechnet maximale Teilsumme der rechten Hälfte: | ||||
|         maxSum2, u2, v2 = MaxSubSumDC(L=Lr); | ||||
|         u2, v2 = u2 + len(Ll), v2 + len(Ll); # offsets kompensieren | ||||
|         ## berechnet maximale Teilsumme mit Überschneidung zw. den Hälften: | ||||
|         maxSum3, u3, v3 = lrRandSum(Ll=Ll, Lr=Lr); | ||||
|         ## bestimme Maximum der 3 Möglichkeiten: | ||||
|         maxSum = max(maxSum1, maxSum2, maxSum3); | ||||
|         if maxSum == maxSum1: | ||||
|             maxSum, u, v = maxSum1, u1, v1; | ||||
|             logDebug('max Teilsumme kommt in linker Partition vor:  Summe L[i] von i={i} .. {j} = {value}'.format(L = L, i = u, j = v, value = maxSum)); | ||||
|         elif maxSum == maxSum3: | ||||
|             maxSum, u, v = maxSum3, u3, v3; | ||||
|             logDebug('max Teilsumme kommt in Überschneidung vor:    Summe L[i] von i={i} .. {j} = {value}'.format(L = L, i = u, j = v, value = maxSum)); | ||||
|         else: # elif maxSum == maxSum2: | ||||
|             maxSum, u, v = maxSum2, u2, v2; | ||||
|             logDebug('max Teilsumme kommt in rechter Partition vor: Summe L[i] von i={i} .. {j} = {value}'.format(L = L, i = u, j = v, value = maxSum)); | ||||
|     return maxSum, u, v; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # AUXILIARY METHODS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| def lrRandSum(Ll: List[float], Lr: List[float]) -> Tuple[float, int, int]: | ||||
|     ''' | ||||
|     Bestimmt maximale Teilsumme einer Teiliste einer Liste, | ||||
|     wobei die Liste in zwei Intervalle partitioniert ist | ||||
|     und die Teilliste beide überschneidet. | ||||
| 
 | ||||
|     Inputs:  Ll, Lr = eine Partition einer Liste von Zahlen in zwei Intervalle | ||||
|     Outputs: maxSum, u=0, v | ||||
|     ''' | ||||
|     maxSumL, u, _ = rRandSum(L=Ll); | ||||
|     maxSumR, _, v = lRandSum(L=Lr); | ||||
|     maxSum = maxSumL + maxSumR; | ||||
|     v += len(Ll)  # offsets kompensieren | ||||
|     return maxSum, u, v; | ||||
| 
 | ||||
| def lRandSum(L: List[float]) -> Tuple[float, int, int]: | ||||
|     ''' | ||||
|     Bestimmt maximale Teilsumme aller nicht leeren linken Segmente einer Liste. | ||||
| 
 | ||||
|     Inputs:  L = Liste von Zahlen | ||||
|     Outputs: maxSum, u(=0), v | ||||
|     ''' | ||||
|     n = len(L); | ||||
|     ## berechne kumulative Summen (vorwärts) | ||||
|     AddToCounter(n); | ||||
|     total = L[0]; | ||||
|     maxSum = total; | ||||
|     u = 0; | ||||
|     v = 0; | ||||
|     for i in range(1, n): | ||||
|         total += L[i]; | ||||
|         if total > maxSum: | ||||
|             v = i; | ||||
|             maxSum = total; | ||||
|     return maxSum, 0, v; | ||||
| 
 | ||||
| def rRandSum(L: List[float]) -> Tuple[float, int, int]: | ||||
|     ''' | ||||
|     Bestimmt maximale Teilsumme aller nicht leeren rechten Segmente einer Liste. | ||||
| 
 | ||||
|     Inputs:  L = Liste von Zahlen | ||||
|     Outputs: maxSum, u, v(=len(L)-1) | ||||
|     ''' | ||||
|     n = len(L); | ||||
|     ## berechne kumulative Summen (rückwärts) | ||||
|     AddToCounter(n); | ||||
|     total = L[n-1]; | ||||
|     maxSum = total; | ||||
|     u = n-1; | ||||
|     v = n-1; | ||||
|     for i in range(0, n-1)[::-1]: | ||||
|         total += L[i]; | ||||
|         if total > maxSum: | ||||
|             u = i; | ||||
|             maxSum = total; | ||||
|     return maxSum, u, v; | ||||
|  | ||||
| @ -1,145 +0,0 @@ | ||||
| #!/usr/bin/env python3 | ||||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # IMPORTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| from local.maths import *; | ||||
| from local.typing import *; | ||||
| 
 | ||||
| from code.core.log import *; | ||||
| from code.algorithms.methods import *; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # GLOBAL VARIABLES/CONSTANTS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # CHECKS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| def preChecks(L: List[int], **_): | ||||
|     assert len(L) > 0, 'Liste darf nicht leer sein.'; | ||||
|     return; | ||||
| 
 | ||||
| def postChecks(L: List[int], **_): | ||||
|     # TODO | ||||
|     return; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # ALGORITHM max sub sum | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| @algorithmInfos(name='MaxSubSum (Maximale Teilsumme mit D & C)', outputnames=('maxSum', 'index_from', 'index_to'), checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks) | ||||
| def MaxSubSumDC(L: List[float]) -> Tuple[float, int, int]: | ||||
|     ''' | ||||
|     Inputs:  L = Liste von Zahlen | ||||
|     Outputs: | ||||
|     - maxSum = Wert der maximalen Summe einer Teilliste aufeinanderfolgender Elemente | ||||
|     - u, v = Indexes so dass die Teilliste [L[u], L[u+1], ..., L[v]] die maximale Summe aufweist | ||||
|     ''' | ||||
|     maxSum = 0; | ||||
|     u = 0; | ||||
|     v = -1; | ||||
|     if len(L) == 1: | ||||
|         ## wenn Liste aus 1 Element besteht, nicht teilen: | ||||
|         if L[0] > maxSum: | ||||
|             v = 0; | ||||
|             maxSum = L[0]; | ||||
|     else: | ||||
|         u = math.ceil(len(L)/2); | ||||
|         Ll = L[:u]; | ||||
|         Lr = L[u:]; | ||||
|         ## berechnet maximale Teilsumme der linken Hälfte: | ||||
|         maxSum1, u1, v1 = MaxSubSumDC(L=Ll); | ||||
|         ## berechnet maximale Teilsumme der rechten Hälfte: | ||||
|         maxSum2, u2, v2 = MaxSubSumDC(L=Lr); | ||||
|         u2, v2 = u2 + len(Ll), v2 + len(Ll); # offsets kompensieren | ||||
|         ## berechnet maximale Teilsumme mit Überschneidung zw. den Hälften: | ||||
|         maxSum3, u3, v3 = lrRandSum(Ll=Ll, Lr=Lr); | ||||
|         ## bestimme Maximum der 3 Möglichkeiten: | ||||
|         maxSum = max(maxSum1, maxSum2, maxSum3); | ||||
|         if maxSum == maxSum1: | ||||
|             maxSum, u, v = maxSum1, u1, v1; | ||||
|             logDebug('max Teilsumme kommt in linker Partition vor:  Summe L[i] von i={i} bis {j} = {value}'.format(L = L, i = u, j = v, value = maxSum)); | ||||
|         elif maxSum == maxSum3: | ||||
|             maxSum, u, v = maxSum3, u3, v3; | ||||
|             logDebug('max Teilsumme kommt in Überschneidung vor:    Summe L[i] von i={i} bis {j} = {value}'.format(L = L, i = u, j = v, value = maxSum)); | ||||
|         else: # elif maxSum == maxSum2: | ||||
|             maxSum, u, v = maxSum2, u2, v2; | ||||
|             logDebug('max Teilsumme kommt in rechter Partition vor: Summe L[i] von i={i} bis {j} = {value}'.format(L = L, i = u, j = v, value = maxSum)); | ||||
|     return maxSum, u, v; | ||||
| 
 | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| # AUXILIARY METHODS | ||||
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| def lrRandSum(Ll: List[float], Lr: List[float]) -> Tuple[float, int, int]: | ||||
|     ''' | ||||
|     Bestimmt maximale Teilsumme einer Teiliste einer Liste, | ||||
|     wobei die Liste in zwei Intervalle partitioniert ist | ||||
|     und die Teilliste beide überschneidet. | ||||
| 
 | ||||
|     Inputs:  Ll, Lr = eine Partition einer Liste von Zahlen in zwei Intervalle | ||||
|     Outputs: maxSum, u=0, v | ||||
|     ''' | ||||
|     maxSumL, u, _ = rRandSum(L=Ll); | ||||
|     maxSumR, _, v = lRandSum(L=Lr); | ||||
|     maxSum = maxSumL + maxSumR; | ||||
|     v += len(Ll)  # offsets kompensieren | ||||
|     return maxSum, u, v; | ||||
| 
 | ||||
| def lRandSum(L: List[float]) -> Tuple[float, int, int]: | ||||
|     ''' | ||||
|     Bestimmt maximale Teilsumme aller nicht leeren linken Segmente einer Liste. | ||||
| 
 | ||||
|     Inputs:  L = Liste von Zahlen | ||||
|     Outputs: maxSum, u(=0), v | ||||
|     ''' | ||||
|     n = len(L); | ||||
|     ## berechne kumulative Summen (vorwärts) | ||||
|     AddToCounter(n); | ||||
|     total = L[0]; | ||||
|     M = [total]; | ||||
|     for i in range(1, n): | ||||
|         total += L[i]; | ||||
|         M.append(total); | ||||
|     ## berechne maximum | ||||
|     AddToCounter(n); | ||||
|     maxSum = M[0]; | ||||
|     u = 0; | ||||
|     v = 0; | ||||
|     for i in range(1, n): | ||||
|         if M[i] > maxSum: | ||||
|             v = i; | ||||
|             maxSum = M[i]; | ||||
|     return maxSum, 0, v; | ||||
| 
 | ||||
| def rRandSum(L: List[float]) -> Tuple[float, int, int]: | ||||
|     ''' | ||||
|     Bestimmt maximale Teilsumme aller nicht leeren rechten Segmente einer Liste. | ||||
| 
 | ||||
|     Inputs:  L = Liste von Zahlen | ||||
|     Outputs: maxSum, u, v(=len(L)-1) | ||||
|     ''' | ||||
|     n = len(L); | ||||
|     ## berechne kumulative Summen (rückwärts) | ||||
|     AddToCounter(n); | ||||
|     total = L[n-1]; | ||||
|     M = [total]; | ||||
|     for i in range(0, n-1)[::-1]: | ||||
|         total += L[i]; | ||||
|         M.insert(0, total); | ||||
|     ## berechne maximum | ||||
|     AddToCounter(n); | ||||
|     maxSum = M[n-1]; | ||||
|     u = n-1; | ||||
|     v = n-1; | ||||
|     for i in range(0, n-1)[::-1]: | ||||
|         if M[i] > maxSum: | ||||
|             u = i; | ||||
|             maxSum = M[i]; | ||||
|     return maxSum, u, v; | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user