Compare commits

..

4 Commits

Author SHA1 Message Date
e19262e818 merge upstream 2025-04-02 09:19:29 +00:00
74f118d11c succ / pred 2025-04-02 11:13:30 +02:00
Oliver Hofmann
36383991d6 fixed off by one in max seq 2025-04-01 14:55:47 +02:00
Oliver Hofmann
06fa81648c basic sort algorithms 2025-04-01 12:38:52 +02:00
12 changed files with 490 additions and 7 deletions

View File

@ -5,7 +5,7 @@
<excludeFolder url="file://$MODULE_DIR$/.venv" />
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.12 (AlgoDatSoSe25)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.12 (SoSe25)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -3,6 +3,7 @@ from utils.memory_cell import MemoryCell
from utils.constants import MIN_VALUE
from utils.memory_manager import MemoryManager
from utils.memory_range import mrange
from utils.literal import Literal
def max_sequence_1(z: MemoryArray):
n = z.length()
@ -13,7 +14,7 @@ def max_sequence_1(z: MemoryArray):
for i in mrange(n):
for j in mrange(i, n):
s.set(0)
for k in mrange(i, j):
for k in mrange(i, j.succ()):
s += z[k]
if s > m:
m.set(s)
@ -21,6 +22,77 @@ def max_sequence_1(z: MemoryArray):
r.set(j)
return m, l, r
def max_sequence_2(z: MemoryArray):
n = z.length()
m = MemoryCell(MIN_VALUE)
s = MemoryCell()
l = MemoryCell()
r = MemoryCell()
for i in mrange(n):
s.set(0)
for j in mrange(i, n):
s += z[j]
if s > m:
m.set(s)
l.set(i)
r.set(j)
return m, l, r
def max_sequence_3(z: MemoryArray, l = None, r = None):
if l is None:
l = Literal(0)
if r is None:
r = z.length().pred()
if l == r:
return z[l], l, r
m = Literal((int(l) + int(r)) // 2)
lm, ll, lr = max_sequence_3(z, l, m)
rm, rl, rr = max_sequence_3(z, m.succ(), r)
zm, zl, zr = find_between(z, l, m, r)
if lm >= rm and lm >= zm:
return lm, ll, lr
if rm >= lm and rm >= zm:
return rm, rl, rr
return zm, zl, zr
def find_between(z: MemoryArray, l, m, r):
max_sum = MemoryCell(MIN_VALUE)
s = MemoryCell(0)
border = MemoryCell()
for i in mrange(m, l.pred(), -1):
s += z[i]
if s > max_sum:
max_sum.set(s)
border.set(i)
left_max = Literal(max_sum)
left_border = Literal(border)
max_sum = MemoryCell(MIN_VALUE)
s.set(0)
for i in mrange(m.succ(), r.succ()):
s += z[i]
if s > max_sum:
max_sum.set(s)
border.set(i)
max_sum += left_max
return max_sum, left_border, border
def max_sequence_4(z: MemoryArray):
n = z.length()
max_sum = MemoryCell(MIN_VALUE)
curr_sum = MemoryCell(0)
curr_left = MemoryCell(0)
r = MemoryCell()
l = MemoryCell()
for i in mrange(n):
curr_sum += z[i]
if curr_sum > max_sum:
max_sum.set(curr_sum)
l.set(curr_left)
r.set(i)
if curr_sum < Literal(0):
curr_sum.set(0)
curr_left.set(i.succ())
return max_sum, l, r
def example(max_sequence_func):
l = [-59, 52, 46, 14, -50, 58, -87, -77, 34, 15]
@ -53,8 +125,9 @@ def analyze_complexity(max_sequence_func, sizes):
if __name__ == '__main__':
example(max_sequence_1)
for filename in ["data/seq0.txt", "data/seq1.txt"]:
print(filename)
seq(filename, max_sequence_1)
analyze_complexity(max_sequence_1, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
for func in [max_sequence_1, max_sequence_2, max_sequence_3, max_sequence_4]:
example(func)
for filename in ["data/seq0.txt", "data/seq1.txt"]:
print(filename)
seq(filename, func)
analyze_complexity(func, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])

53
utils/game.py Normal file
View File

@ -0,0 +1,53 @@
import pygame
class Game:
def __init__(self, title, fps=60, size=(640, 400)):
self.title = title
self.fps = fps
self.size = size
self.clock = pygame.time.Clock()
self.dt = 0
self.screen = None
def init_game(self):
pygame.init()
pygame.display.set_caption(self.title)
self.screen = pygame.display.set_mode(self.size)
def game_loop(self):
while True:
# Berechnung der Zeitdifferenz seit dem letzten Frame
self.dt = self.clock.tick(self.fps) / 1000
if self.event_handling() == False:
break
if self.update_game() == False:
break
self.draw_game()
def exit_game(self):
pygame.quit()
def event_handling(self): # bleibt in der Unterklasse unverändert
for event in pygame.event.get():
if not self.handle_event(event):
return False
return True
def handle_event(self, event): # wird in der Unterklasse überschrieben
if event.type == pygame.QUIT:
return False
return True
def update_game(self):
return True
def draw_game(self):
pygame.display.flip()
def run(self):
self.init_game()
self.game_loop()
self.exit_game()

View File

@ -71,6 +71,10 @@ class Literal:
"""Repräsentation des Werts."""
return f"{self.value}"
def __repr__(self):
"""Repräsentation des Werts für Debugging-Zwecke."""
return f"Literal(value={self.value}, reads={self.read_count})"
def get_read_count(self):
"""Gibt zurück, wie oft der Wert gelesen wurde."""
return self.read_count
@ -80,6 +84,12 @@ class Literal:
self.read_count += 1
return int(self.value)
def succ(self):
return Literal(self.value+1)
def pred(self):
return Literal(self.value-1)
if __name__ == "__main__":
l1 = Literal(5)

View File

@ -73,6 +73,14 @@ class MemoryArray:
a.reset_counters()
return a
@staticmethod
def create_sorted_array(count):
"""Erzeugt ein sortiertes Speicherarray."""
a = MemoryArray(list(range(count)))
a.reset_counters()
return a
@staticmethod
def create_array_from_file(filename, limit=None):
"""Erzeugt ein Speicherarray aus einer Datei."""

View File

@ -0,0 +1,13 @@
from utils.memory_cell import MemoryCell
from utils.literal import Literal
x = MemoryCell(int(input("Erste Zahl: ")))
y = MemoryCell(int(input("Zweite Zahl: ")))
while x > Literal(0):
if x < y:
x, y = y, x
x -= y
print(y)
print(f"Insgesamt gab es {x.sub_count + y.sub_count} Subtraktionen.")

View File

@ -0,0 +1,41 @@
import random
import pygame
from utils.game import Game
from utils.memory_array import MemoryArray
from bubble_sorting import bubble_sort_stepwise
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
class BubbleGame(Game):
def __init__(self):
super().__init__("Bubble Game", fps=60, size=(400, 400))
random.seed()
l =list(range(1, 101))
random.shuffle(l)
self.z = MemoryArray(l)
self.finished = False
self.sort_generator = bubble_sort_stepwise(self.z)
def update_game(self):
if not self.finished:
try:
next(self.sort_generator)
except StopIteration:
self.finished = True
return True
def draw_game(self):
self.screen.fill(WHITE)
for i, cell in enumerate(self.z):
x = 50 + i*3
y = 350 - cell.value * 3
pygame.draw.rect(self.screen, BLUE, (x, y, 3, 3))
super().draw_game()
if __name__ == "__main__":
b = BubbleGame()
b.run()

View File

@ -0,0 +1,84 @@
from utils.memory_array import MemoryArray
from utils.memory_cell import MemoryCell
from utils.constants import MIN_VALUE
from utils.memory_manager import MemoryManager
from utils.memory_range import mrange
from utils.literal import Literal
def bubble_sort_stepwise(z: MemoryArray):
n = z.length()
for i in mrange(n.pred()):
for j in mrange(n.pred(), i, -1):
if z[j.pred()] > z[j]:
swap(z, j, j.pred())
yield z
def bubble_sort2_stepwise(z: MemoryArray):
n = MemoryCell(z.length())
true = Literal(1)
false = Literal(0)
sortiert = MemoryCell()
while True:
sortiert.set(true)
for i in mrange(n.pred()):
if z[i] > z[i.succ()]:
swap(z, i, i.succ())
sortiert.set(false)
yield z
n -= Literal(1)
if sortiert == true or n <= Literal(1):
break
def bubble_sort(z: MemoryArray):
sort_generator = bubble_sort_stepwise(z)
while True:
try:
next(sort_generator)
except StopIteration:
break
def bubble_sort2(z: MemoryArray):
sort_generator = bubble_sort2_stepwise(z)
while True:
try:
next(sort_generator)
except StopIteration:
break
def sort_file(filename, sort_func):
z = MemoryArray.create_array_from_file(filename)
sort_func(z)
return z
def analyze_complexity(sort_func, sizes, presorted=False):
"""
Analysiert die Komplexität einer Sortierfunktion.
:param sort_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
if presorted:
random_array = MemoryArray.create_sorted_array(size)
else:
random_array = MemoryArray.create_random_array(size, -100, 100)
sort_func(random_array)
MemoryManager.save_stats(size)
MemoryManager.plot_stats(["cells", "compares", "writes"])
def swap(z: MemoryArray, i: int, j: int):
tmp = z[Literal(i)].value
z[Literal(i)] = z[Literal(j)]
z[Literal(j)].set(tmp)
if __name__ == '__main__':
analyze_complexity(bubble_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
# analyze_complexity(bubble_sort2, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
# analyze_complexity(bubble_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100], True)
# analyze_complexity(bubble_sort2, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100], True)

View File

@ -0,0 +1,41 @@
import random
import pygame
from utils.game import Game
from utils.memory_array import MemoryArray
from insert_sorting import insert_sort_stepwise
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
class InsertGame(Game):
def __init__(self):
super().__init__("Insert Game", fps=60, size=(400, 400))
random.seed()
l =list(range(1, 101))
random.shuffle(l)
self.z = MemoryArray(l)
self.finished = False
self.sort_generator = insert_sort_stepwise(self.z)
def update_game(self):
if not self.finished:
try:
next(self.sort_generator)
except StopIteration:
self.finished = True
return True
def draw_game(self):
self.screen.fill(WHITE)
for i, cell in enumerate(self.z):
x = 50 + i*3
y = 350 - cell.value * 3
pygame.draw.rect(self.screen, BLUE, (x, y, 3, 3))
super().draw_game()
if __name__ == "__main__":
b = InsertGame()
b.run()

View File

@ -0,0 +1,61 @@
from utils.memory_array import MemoryArray
from utils.memory_cell import MemoryCell
from utils.memory_manager import MemoryManager
from utils.memory_range import mrange
from utils.literal import Literal
def insert_sort_stepwise(z: MemoryArray):
n = z.length()
j = MemoryCell()
elem = MemoryCell()
for i in mrange(n):
elem.set(z[i])
j.set(i)
while j > Literal(0) and z[j.pred()] > elem:
z[j].set(z[j.pred()])
j -= Literal(1)
yield z
z[j].set(elem)
yield z
def insert_sort(z: MemoryArray):
sort_generator = insert_sort_stepwise(z)
while True:
try:
next(sort_generator)
except StopIteration:
break
def sort_file(filename, sort_func):
z = MemoryArray.create_array_from_file(filename)
sort_func(z)
return z
def analyze_complexity(sort_func, sizes, presorted=False):
"""
Analysiert die Komplexität einer Sortierfunktion.
:param sort_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
if presorted:
random_array = MemoryArray.create_sorted_array(size)
else:
random_array = MemoryArray.create_random_array(size, -100, 100)
sort_func(random_array)
MemoryManager.save_stats(size)
MemoryManager.plot_stats(["cells", "compares", "writes"])
def swap(z: MemoryArray, i: int, j: int):
tmp = z[Literal(i)].value
z[Literal(i)] = z[Literal(j)]
z[Literal(j)].set(tmp)
if __name__ == '__main__':
analyze_complexity(insert_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
analyze_complexity(insert_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100], True)

View File

@ -0,0 +1,41 @@
import random
import pygame
from utils.game import Game
from utils.memory_array import MemoryArray
from select_sorting import select_sort_stepwise
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
class SelectGame(Game):
def __init__(self):
super().__init__("Select Game", fps=60, size=(400, 400))
random.seed()
l =list(range(1, 101))
random.shuffle(l)
self.z = MemoryArray(l)
self.finished = False
self.sort_generator = select_sort_stepwise(self.z)
def update_game(self):
if not self.finished:
try:
next(self.sort_generator)
except StopIteration:
self.finished = True
return True
def draw_game(self):
self.screen.fill(WHITE)
for i, cell in enumerate(self.z):
x = 50 + i*3
y = 350 - cell.value * 3
pygame.draw.rect(self.screen, BLUE, (x, y, 3, 3))
super().draw_game()
if __name__ == "__main__":
b = SelectGame()
b.run()

View File

@ -0,0 +1,58 @@
from utils.memory_array import MemoryArray
from utils.memory_cell import MemoryCell
from utils.memory_manager import MemoryManager
from utils.memory_range import mrange
from utils.literal import Literal
def select_sort_stepwise(z: MemoryArray):
n = z.length()
cur_min = MemoryCell()
for i in mrange(n):
cur_min.set(i)
for j in mrange(i.succ(), n):
if z[j] < z[cur_min]:
cur_min.set(j)
swap(z, i, int(cur_min))
yield z
def select_sort(z: MemoryArray):
sort_generator = select_sort_stepwise(z)
while True:
try:
next(sort_generator)
except StopIteration:
break
def sort_file(filename, sort_func):
z = MemoryArray.create_array_from_file(filename)
sort_func(z)
return z
def analyze_complexity(sort_func, sizes, presorted=False):
"""
Analysiert die Komplexität einer Sortierfunktion.
:param sort_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
if presorted:
random_array = MemoryArray.create_sorted_array(size)
else:
random_array = MemoryArray.create_random_array(size, -100, 100)
sort_func(random_array)
MemoryManager.save_stats(size)
MemoryManager.plot_stats(["cells", "compares", "writes"])
def swap(z: MemoryArray, i: int, j: int):
tmp = z[Literal(i)].value
z[Literal(i)] = z[Literal(j)]
z[Literal(j)].set(tmp)
if __name__ == '__main__':
analyze_complexity(select_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
# analyze_complexity(select_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100], True)