diff --git a/code/golang/pkg/algorithms/stacks/next_greater_element/next_greater_element.go b/code/golang/pkg/algorithms/stacks/next_greater_element/next_greater_element.go index 86e5769..d65d371 100644 --- a/code/golang/pkg/algorithms/stacks/next_greater_element/next_greater_element.go +++ b/code/golang/pkg/algorithms/stacks/next_greater_element/next_greater_element.go @@ -34,52 +34,45 @@ func NextGreaterElement(L []int) [][2]int { S := stacks.CREATE() for i := 0; i < len(L); i++ { - logging.Debug("Lies Element L[%v] ein", i) + logging.Debug("Nächstes List-Element L[%v] = %v betrachten", i, L[i]) nextElement := L[i] + logging.Debug("Entferne alle top Elemente vom Stack bis >= nextElement") + /* + Entferne alle top Elemente vom Stack < nextElement + bis oben ein Elment >= nextElement ist, oder Stack leer ist. + */ logging.Debug("Stack S | %v", S) - if !S.EMPTY() { - logging.Debug("Entferne alle top Elemente vom Stack bis >= nextElement") + for !S.EMPTY() { element := S.TOP() S.POP() - metrics.AddTimeCost() - /* - Entferne kleinere Elemente vom Stack - Aktuelles Element ist jeweils größerer rechter Partner - */ - for element < nextElement { - logging.Debug("Stack S | %v", S) + metrics.AddMovesCost() + logging.Debug("Stack S | %v; (popped) Top-Element = %v", S, element) + // falls element < next Element, zum Output hinzufügen + if element < nextElement { addToOutput(element, nextElement) - if S.EMPTY() { - break - } - element = S.TOP() - S.POP() - metrics.AddTimeCost() - } - - // lege letztes Element zurück - if element > nextElement { - logging.Debug("Element >= nextElement zurücklegen") + // sonst Element auf Stack zurücklegen und Schleife abbrechen. + } else { + logging.Debug("Stack-Element >= nextElement ==> zurücklegen") S.PUSH(element) - metrics.AddTimeCost() + metrics.AddMovesCost() + break } - logging.Debug("Stack S | %v", S) } - S.PUSH(nextElement) - metrics.AddTimeCost() logging.Debug("L[%v] auf Stack legen", i) + S.PUSH(nextElement) logging.Debug("Stack S | %v", S) + metrics.AddMovesCost() } // was übrig bleibt hat kein größeres Element logging.Debug("Alles übrige auf Stack hat kein nächstes größeres Element") for !S.EMPTY() { - metrics.AddTimeCost() logging.Debug("Stack S | %v", S) element := S.TOP() S.POP() + metrics.AddMovesCost() addToOutput(element, -1) } logging.Debug("Stack S | %v", S) diff --git a/code/python/src/algorithms/exports.py b/code/python/src/algorithms/exports.py index 0601527..ed772f5 100644 --- a/code/python/src/algorithms/exports.py +++ b/code/python/src/algorithms/exports.py @@ -6,4 +6,5 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ from src.algorithms.search.exports import *; +from src.algorithms.stacks.exports import *; from src.algorithms.sum.exports import *; diff --git a/code/python/src/algorithms/stacks/__init__.py b/code/python/src/algorithms/stacks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/code/python/src/algorithms/stacks/exports.py b/code/python/src/algorithms/stacks/exports.py new file mode 100644 index 0000000..9bae8e3 --- /dev/null +++ b/code/python/src/algorithms/stacks/exports.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.algorithms.stacks.next_greater_element import NextGreaterElement; diff --git a/code/python/src/algorithms/stacks/next_greater_element.py b/code/python/src/algorithms/stacks/next_greater_element.py new file mode 100644 index 0000000..93fc06b --- /dev/null +++ b/code/python/src/algorithms/stacks/next_greater_element.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from src.local.typing import *; + +from src.core.log import *; +from src.core.metrics import *; +from src.data_structures.stacks import Stack; +from src.algorithms.methods import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# GLOBAL VARIABLES/CONSTANTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +_output_list: List[Tuple[int,int]] + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# CHECKS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def preChecks(L: List[int], **_): + # TODO + return; + +def postChecks(L: List[int], **_): + # TODO + return; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ALGORITHM next greater element +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +@algorithmInfos(name='NextGreaterElement (with stacks)', outputnames=['pairs'], preChecks=preChecks, postChecks=postChecks) +def NextGreaterElement(L: List[int]) -> List[Tuple[int,int]]: + ''' + Inputs: L = Liste von Zahlen, x = Zahl. + Outputs: Liste von Paaren von Elementen und ihrem nächsten größeren Element + ''' + clearOutput(); + + S = Stack(); + S.INIT(); + + for i in range(len(L)): + logDebug('Nächstes List-Element L[{i}] = {el} betrachten'.format(i=i, el=L[i])); + nextElement = L[i]; + + logDebug('Entferne alle top Elemente vom Stack bis >= nextElement'); + # Entferne alle top Elemente vom Stack < nextElement + # bis oben ein Elment >= nextElement ist, oder Stack leer ist. + logDebug('Stack S | {S}'.format(S=S)); + while not S.EMPTY(): + element = S.TOP(); + S.POP(); + AddMovesCost(); + logDebug('Stack S | {S}; (popped) Top-Element = {el}'.format(S=S, el=element)) + # falls element < next Element, zum Output hinzufügen + if element < nextElement: + addToOutput(element, nextElement); + # sonst Element auf Stack zurücklegen und Schleife abbrechen. + else: + logDebug('Stack element >= nextElement ==> zurücklegen') + S.PUSH(element); + AddMovesCost(); + break; + logDebug('Stack S | {S}'.format(S=S)); + + logDebug('L[{i}] auf Stack legen'.format(i=i)); + S.PUSH(nextElement); + logDebug('Stack S | {S}'.format(S=S)); + AddMovesCost(); + + # was übrig bleibt hat kein größeres Element + logDebug('Alles übrige auf Stack hat kein nächstes größeres Element') + while not S.EMPTY(): + logDebug('Stack S | {S}'.format(S=S)); + element = S.TOP(); + S.POP(); + AddMovesCost(); + addToOutput(element, -1); + + logDebug('Stack S | {S}'.format(S=S)) + return output(); + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# AUXILIARY METHODS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def clearOutput(): + global _output_list; + _output_list = []; + return; + +def addToOutput(m: int, n: int): + global _output_list; + _output_list.append((m, n)) + return; + +def output() -> List[Tuple[int, int]]: + global _output_list; + output = _output_list[:] # erstelle Kopie + clearOutput() + return output diff --git a/code/python/src/data_structures/__init__.py b/code/python/src/data_structures/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/code/python/src/data_structures/stacks.py b/code/python/src/data_structures/stacks.py new file mode 100644 index 0000000..8617909 --- /dev/null +++ b/code/python/src/data_structures/stacks.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from local.typing import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# GLOBAL VARIABLES/CONSTANTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# CLASS Stack +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class Stack(object): + values: List[int]; + + def INIT(self): + self.values = []; + + def EMPTY(self) -> bool: + return len(self.values) == 0; + + def PUSH(self, x: int): + self.values.append(x); + + def TOP(self) -> int: + if self.EMPTY(): + raise Exception('Cannot pop from empty stack!') + return self.values[-1]; + + def POP(self) -> int: + x = self.TOP() + self.values = self.values[:-1] + return x + + def __str__(self) -> str: + if len(self.values) == 0: + return '-'; + return ', '.join([str(x) for x in self.values]); diff --git a/code/python/src/endpoints/run.py b/code/python/src/endpoints/run.py index 158cddd..d1fa065 100644 --- a/code/python/src/endpoints/run.py +++ b/code/python/src/endpoints/run.py @@ -39,11 +39,7 @@ def runNonInteractive(path: str): DisplayStartOfCase(caseindex, descr); try: - if command == 'algorithm-sum-maxsub': - MaxSubSum(L=inputs['L']); - elif command == 'algorithm-sum-maxsub-dc': - MaxSubSumDC(L=inputs['L']); - elif command == 'algorithm-search-sequential': + if command == 'algorithm-search-sequential': SequentialSearch(L=inputs['L'], x=inputs['x']); elif command == 'algorithm-search-binary': BinarySearch(L=inputs['L'], x=inputs['x']); @@ -61,6 +57,12 @@ def runNonInteractive(path: str): FindPoison(L=inputs['L']); elif command == 'algorithm-search-poison-fast': FindPoisonFast(L=inputs['L']); + elif command == 'algorithm-stacks-next-greater-element': + NextGreaterElement(L=inputs['L']); + elif command == 'algorithm-sum-maxsub': + MaxSubSum(L=inputs['L']); + elif command == 'algorithm-sum-maxsub-dc': + MaxSubSumDC(L=inputs['L']); else: raise ValueError('Command \033[1m{}\033[0m nicht erkannt'.format(command)); except Exception as e: