diff --git a/schoeffelbe/pr02.py b/schoeffelbe/pr02.py new file mode 100644 index 0000000..8b65f0a --- /dev/null +++ b/schoeffelbe/pr02.py @@ -0,0 +1,115 @@ +import logging +logger = logging.getLogger(__name__) +# logging.basicConfig(level=logging.DEBUG) + +from utils.memory_array import MemoryArray +from utils.memory_cell import MemoryCell +from utils.literal import Literal +from utils.constants import MIN_VALUE +from utils.memory_manager import MemoryManager +from utils.memory_range import mrange + +def example(): + initial = [6, 5, 3, 8, 1, 7, 2, 4] + # initial = [-6, -5, -3, -8, 1, 7, 2, 4] + toSort = MemoryArray(initial) + # init_from_size not accessible? + sorted = MemoryArray([-1] * len(initial)) + mergeSort(toSort, sorted) + logger.debug(f"sorted {sorted} vs initial {initial}") + assert all(sorted[Literal(i)] == Literal(i+1) for i in range(len(initial))), "Array not sorted correctly" + + analyze_complexity(mergeSort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]) + +def merge(left: MemoryArray, right: MemoryArray, sort: MemoryArray): + pointerLeft = MemoryCell(0) + pointerRight = MemoryCell(0) + pointerSort = MemoryCell(0) + + compare = lambda x, y: x <= y + + logger.debug(f"Merging left {left} with right {right} in sort {sort}") + + while pointerLeft < left.length() and pointerRight < right.length(): + if compare(left[pointerLeft], right[pointerRight]): + sort[pointerSort] = left[pointerLeft] + pointerLeft += Literal(1) + else: + sort[pointerSort] = right[pointerRight] + pointerRight += Literal(1) + + logger.debug(f"Now are at sort {sort} with {pointerLeft} (l) and {pointerRight} (r)") + pointerSort += Literal(1) + + # Consume remaining elements + while pointerLeft < left.length(): + logger.debug(f"Consuming left {left} from {pointerSort} at {pointerLeft}") + sort[pointerSort] = left[pointerLeft] + pointerLeft += Literal(1) + pointerSort += Literal(1) + + while pointerRight < right.length(): + logger.debug(f"Consuming right {right} from {pointerSort} at {pointerRight}") + sort[pointerSort] = right[pointerRight] + pointerRight += Literal(1) + pointerSort += Literal(1) + +# Sort the array passed as "toSort" and place the result in array "sort" +# Does not change the original Array +def mergeSort(toSort: MemoryArray, sort: MemoryArray): + logger.debug(toSort) + toSortLength = MemoryCell(toSort.length()) + + # Splitting + # Rec-Term -> Reached single Element. Single Element is already sorted so we place it! + if toSortLength <= Literal(1): + # still working for empty array + if toSortLength == Literal(1): + sort[Literal(0)] = toSort[Literal(0)] + return + + # TODO - Use a global var or a reference to an array passed as argument for this + # TODO - Tried non-temp-array approach with alternating Work-Arrays passed to the function, but made code really unreadable. Decided not worth it for now + # Temporary Arrays to hold the split arrays + mid : Literal = toSortLength // Literal(2) + left : MemoryArray = MemoryArray([toSort[i] for i in mrange(mid)]) + right : MemoryArray = MemoryArray([toSort[i] for i in mrange(mid, toSortLength)]) + + # Temporary arrays for sorted halves + leftSort = MemoryArray([-1] * mid.get()) + rightSort = MemoryArray([-1] * (toSortLength - mid).get()) + + # Split further + mergeSort(left, leftSort) + mergeSort(right, rightSort) + + # Recreate the array from the seperated parts + merge(leftSort, rightSort, sort) + +def analyze_complexity(fn, sizes): + """ + Analysiert die Komplexität einer maximalen Teilfolgenfunktion. + + :param max_sequence_func: Die Funktion, die analysiert wird. + :param sizes: Eine Liste von Eingabegrößen für die Analyse. + """ + for size in sizes: + MemoryManager.purge() # Speicher zurücksetzen + random_array = MemoryArray.create_random_array(size, -100, 100) + other_array = MemoryArray([-1] * size) + fn(random_array, other_array) + MemoryManager.save_stats(size) + + MemoryManager.plot_stats(["cells", "adds", "compares"]) + + +if __name__ == '__main__': + # For debug, assert if working and complexity-analysis + # example() + + for filename in ["data/seq0.txt", "data/seq1.txt", "data/seq2.txt", "data/seq3.txt"]: + print(filename) + toSort = MemoryArray.create_array_from_file(filename) + sorted = MemoryArray([-1] * toSort.length().get()) + mergeSort(toSort, sorted) + print(sorted)