Umstellen der Auswertungslogik
This commit is contained in:
parent
c48b5c7e59
commit
1dfdff9391
@ -1,4 +1,6 @@
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_int import Int
|
||||
from utils.algo_array import Array
|
||||
from utils.algo_range import irange
|
||||
from utils.algo_range import Range
|
||||
from utils.algo_path import path
|
||||
from utils.algo_priority_queue import PriorityQueue
|
||||
|
||||
@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
from random import randint
|
||||
from utils.algo_context import AlgoContext, _NullContext, NULL_CTX
|
||||
from utils.algo_int import Int
|
||||
from utils.project_dir import get_path
|
||||
from utils.algo_path import path
|
||||
|
||||
|
||||
class Array:
|
||||
@ -130,8 +130,8 @@ class Array:
|
||||
limit : int | None
|
||||
Optionale Obergrenze für die Anzahl eingelesener Zeilen.
|
||||
"""
|
||||
path = get_path(filename)
|
||||
with open(path) as f:
|
||||
filepath = path(filename)
|
||||
with open(filepath) as f:
|
||||
lines = f.readlines()
|
||||
if limit is not None:
|
||||
lines = lines[:limit]
|
||||
|
||||
@ -117,7 +117,7 @@ class _NullContext:
|
||||
"""
|
||||
Kontext der alle Operationen stillschweigend ignoriert.
|
||||
|
||||
Wird intern von irange() verwendet, damit Schleifenindex-Arithmetik
|
||||
Wird intern von Range() verwendet, damit Schleifenindex-Arithmetik
|
||||
standardmäßig nicht mitgezählt wird.
|
||||
|
||||
__setattr__ ist absichtlich ein no-op: ``ctx.reads += 1`` bleibt wirkungslos.
|
||||
|
||||
@ -212,6 +212,14 @@ class Int:
|
||||
self._value //= other._value
|
||||
return self
|
||||
|
||||
def __imod__(self, other):
|
||||
other = self._wrap(other)
|
||||
self._ctx.reads += 2
|
||||
self._ctx.divisions += 1
|
||||
self._ctx.writes += 1
|
||||
self._value %= other._value
|
||||
return self
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Bitoperationen (2 reads + 1 bitop + 1 write für in-place)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@ -3,14 +3,14 @@ from utils.algo_context import AlgoContext, NULL_CTX
|
||||
from utils.algo_int import Int
|
||||
|
||||
|
||||
def irange(start_or_stop, stop=None, step: int = 1, ctx: AlgoContext = None):
|
||||
def Range(start_or_stop, stop=None, step: int = 1, ctx: AlgoContext = None):
|
||||
"""
|
||||
Drop-in Ersatz für range(), der Int-Objekte zurückgibt.
|
||||
|
||||
Wird wie Pythons range() aufgerufen:
|
||||
irange(stop)
|
||||
irange(start, stop)
|
||||
irange(start, stop, step)
|
||||
Range(stop)
|
||||
Range(start, stop)
|
||||
Range(start, stop, step)
|
||||
|
||||
Indexarithmetik und Zählung
|
||||
---------------------------
|
||||
@ -20,13 +20,13 @@ def irange(start_or_stop, stop=None, step: int = 1, ctx: AlgoContext = None):
|
||||
sollen in die Komplexitätsanalyse einfließen.
|
||||
|
||||
Mit ctx-Argument werden auch Indexoperationen gezählt:
|
||||
for j in irange(n, ctx=ctx): ...
|
||||
for j in Range(n, ctx=ctx): ...
|
||||
|
||||
Beispiel
|
||||
--------
|
||||
ctx = AlgoContext()
|
||||
z = Array.random(10, 0, 99, ctx)
|
||||
for i in irange(len(z) - 1): # i ist Int, Arithmetik nicht gezählt
|
||||
for i in Range(len(z) - 1): # i ist Int, Arithmetik nicht gezählt
|
||||
if z[i] > z[i + 1]: # Vergleich gezählt (z-Zellen haben ctx)
|
||||
z.swap(i, i + 1)
|
||||
"""
|
||||
@ -38,7 +38,7 @@ def irange(start_or_stop, stop=None, step: int = 1, ctx: AlgoContext = None):
|
||||
start, stop_ = int(start_or_stop), int(stop)
|
||||
step = int(step)
|
||||
|
||||
assert step != 0, "irange: step darf nicht 0 sein"
|
||||
assert step != 0, "Range: step darf nicht 0 sein"
|
||||
|
||||
num = start
|
||||
if step > 0:
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
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()
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
import heapq
|
||||
|
||||
class PriorityQueue:
|
||||
def __init__(self):
|
||||
self.heap = []
|
||||
self.entry_finder = {} # map: item -> [priority, item]
|
||||
self.REMOVED = '<removed>'
|
||||
self.counter = 0 # unique sequence count to break ties
|
||||
|
||||
def add_or_update(self, item, priority):
|
||||
if item in self.entry_finder:
|
||||
self.remove(item)
|
||||
count = self.counter
|
||||
entry = [priority, count, item]
|
||||
self.entry_finder[item] = entry
|
||||
heapq.heappush(self.heap, entry)
|
||||
self.counter += 1
|
||||
|
||||
def remove(self, item):
|
||||
entry = self.entry_finder.pop(item)
|
||||
entry[-1] = self.REMOVED # mark as removed
|
||||
|
||||
def pop(self):
|
||||
while self.heap:
|
||||
priority, count, item = heapq.heappop(self.heap)
|
||||
if item != self.REMOVED:
|
||||
del self.entry_finder[item]
|
||||
return item, priority
|
||||
return None
|
||||
|
||||
if __name__ == "__main__":
|
||||
pq = PriorityQueue()
|
||||
pq.add_or_update('task1', 1)
|
||||
pq.add_or_update('task2', float('inf'))
|
||||
pq.add_or_update('task3', float('inf'))
|
||||
|
||||
print(pq.pop()) # Should print ('task1', 1)
|
||||
pq.add_or_update('task2', 0) # Update priority of 'task1'
|
||||
print(pq.pop()) # Should print ('task2', 0)
|
||||
print(pq.pop()) # Should print ('task3', 3)
|
||||
@ -1,13 +0,0 @@
|
||||
from pathlib import Path
|
||||
|
||||
def get_path(filename) -> Path:
|
||||
this_dir = Path(__file__).resolve().parent
|
||||
project_dir = this_dir.parent
|
||||
return project_dir / filename
|
||||
|
||||
if __name__ == "__main__":
|
||||
filename = get_path("data/seq0.txt")
|
||||
print(filename)
|
||||
print(filename.resolve())
|
||||
print(filename.is_file())
|
||||
print(filename.exists())
|
||||
@ -1,175 +0,0 @@
|
||||
import unittest
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_int import Int
|
||||
from utils.algo_array import Array
|
||||
|
||||
|
||||
class TestArray(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.ctx = AlgoContext()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Erzeugung
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_from_list(self):
|
||||
z = Array([3, 1, 4, 1, 5], self.ctx)
|
||||
self.assertEqual(len(z), 5)
|
||||
self.assertEqual(z[0].value, 3)
|
||||
self.assertEqual(z[4].value, 5)
|
||||
|
||||
def test_random(self):
|
||||
z = Array.random(20, 0, 99, self.ctx)
|
||||
self.assertEqual(len(z), 20)
|
||||
for cell in z:
|
||||
self.assertGreaterEqual(cell.value, 0)
|
||||
self.assertLessEqual(cell.value, 99)
|
||||
|
||||
def test_sorted(self):
|
||||
z = Array.sorted(5, self.ctx)
|
||||
values = [z[i].value for i in range(5)]
|
||||
self.assertEqual(values, [0, 1, 2, 3, 4])
|
||||
|
||||
def test_from_file(self):
|
||||
z = Array.from_file("data/seq0.txt", self.ctx)
|
||||
self.assertGreater(len(z), 0)
|
||||
|
||||
def test_random_uses_no_write_counts(self):
|
||||
"""Fabrikmethoden sollen keine Schreibzugriffe verzeichnen."""
|
||||
z = Array.random(10, 0, 9, self.ctx)
|
||||
self.assertEqual(self.ctx.writes, 0)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Zugriff
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_getitem_returns_int_cell(self):
|
||||
z = Array([10, 20], self.ctx)
|
||||
cell = z[0]
|
||||
self.assertIsInstance(cell, Int)
|
||||
self.assertEqual(cell.value, 10)
|
||||
|
||||
def test_getitem_with_int_index(self):
|
||||
z = Array([10, 20, 30], self.ctx)
|
||||
i = Int(2, self.ctx)
|
||||
self.assertEqual(z[i].value, 30)
|
||||
|
||||
def test_getitem_no_read_count(self):
|
||||
"""Array-Zugriff allein soll keinen read-Zähler erhöhen."""
|
||||
z = Array([5, 6, 7], self.ctx)
|
||||
_ = z[0]
|
||||
self.assertEqual(self.ctx.reads, 0)
|
||||
|
||||
def test_setitem_plain_int(self):
|
||||
z = Array([1, 2, 3], self.ctx)
|
||||
z[0] = 99
|
||||
self.assertEqual(z[0].value, 99)
|
||||
self.assertEqual(self.ctx.writes, 1)
|
||||
self.assertEqual(self.ctx.reads, 0)
|
||||
|
||||
def test_setitem_int_object(self):
|
||||
z = Array([1, 2, 3], self.ctx)
|
||||
v = Int(42, self.ctx)
|
||||
z[1] = v
|
||||
self.assertEqual(z[1].value, 42)
|
||||
self.assertEqual(self.ctx.writes, 1)
|
||||
self.assertEqual(self.ctx.reads, 1)
|
||||
|
||||
def test_setitem_cell_to_cell(self):
|
||||
"""z[i] = z[j] kopiert den Wert (keine Alias-Referenz)."""
|
||||
z = Array([10, 20], self.ctx)
|
||||
z[0] = z[1]
|
||||
self.assertEqual(z[0].value, 20)
|
||||
# Wert ändern – z[1] darf sich nicht mitändern
|
||||
z[0] = 99
|
||||
self.assertEqual(z[1].value, 20)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Swap
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_swap_exchanges_values(self):
|
||||
z = Array([1, 2, 3, 4, 5], self.ctx)
|
||||
z.swap(0, 4)
|
||||
self.assertEqual(z[0].value, 5)
|
||||
self.assertEqual(z[4].value, 1)
|
||||
|
||||
def test_swap_counts_reads_and_writes(self):
|
||||
z = Array([1, 2], self.ctx)
|
||||
z.swap(0, 1)
|
||||
self.assertEqual(self.ctx.reads, 2)
|
||||
self.assertEqual(self.ctx.writes, 2)
|
||||
|
||||
def test_swap_with_int_indices(self):
|
||||
z = Array([10, 20, 30], self.ctx)
|
||||
i = Int(0, self.ctx)
|
||||
j = Int(2, self.ctx)
|
||||
z.swap(i, j)
|
||||
self.assertEqual(z[0].value, 30)
|
||||
self.assertEqual(z[2].value, 10)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Vergleich über Array-Zellen (zählt beim Int, nicht beim Array)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_cell_comparison_counts_in_ctx(self):
|
||||
z = Array([5, 3], self.ctx)
|
||||
result = z[0] > z[1]
|
||||
self.assertTrue(result)
|
||||
self.assertEqual(self.ctx.comparisons, 1)
|
||||
self.assertEqual(self.ctx.reads, 2)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Iteration
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_iteration(self):
|
||||
z = Array([1, 2, 3], self.ctx)
|
||||
values = [c.value for c in z]
|
||||
self.assertEqual(values, [1, 2, 3])
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Länge
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_len(self):
|
||||
z = Array([1, 2, 3, 4], self.ctx)
|
||||
self.assertEqual(len(z), 4)
|
||||
|
||||
def test_length_returns_int(self):
|
||||
z = Array([1, 2, 3], self.ctx)
|
||||
n = z.length()
|
||||
self.assertIsInstance(n, Int)
|
||||
self.assertEqual(n.value, 3)
|
||||
|
||||
|
||||
class TestArrayIntegration(unittest.TestCase):
|
||||
"""Bubble Sort als Integrationstest für das gesamte Framework."""
|
||||
|
||||
def test_bubble_sort_produces_correct_result(self):
|
||||
import sys, os
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__),
|
||||
'../vorlesung/L02_elementares_sortieren'))
|
||||
from bubble_sorting import bubble_sort
|
||||
ctx = AlgoContext()
|
||||
z = Array([5, 3, 1, 4, 2], ctx)
|
||||
bubble_sort(z, ctx)
|
||||
values = [z[i].value for i in range(len(z))]
|
||||
self.assertEqual(values, [1, 2, 3, 4, 5])
|
||||
|
||||
def test_bubble_sort_counts_comparisons(self):
|
||||
import sys, os
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__),
|
||||
'../vorlesung/L02_elementares_sortieren'))
|
||||
from bubble_sorting import bubble_sort
|
||||
ctx = AlgoContext()
|
||||
z = Array([5, 4, 3, 2, 1], ctx) # worst case
|
||||
bubble_sort(z, ctx)
|
||||
# n=5: maximal n*(n-1)/2 = 10 Vergleiche
|
||||
self.assertGreater(ctx.comparisons, 0)
|
||||
self.assertLessEqual(ctx.comparisons, 10)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@ -1,193 +0,0 @@
|
||||
import unittest
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_int import Int
|
||||
|
||||
|
||||
class TestInt(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.ctx = AlgoContext()
|
||||
|
||||
def _int(self, v):
|
||||
return Int(v, self.ctx)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Vergleiche
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_comparison_counts_reads_and_compare(self):
|
||||
a, b = self._int(5), self._int(3)
|
||||
result = a > b
|
||||
self.assertTrue(result)
|
||||
self.assertEqual(self.ctx.comparisons, 1)
|
||||
self.assertEqual(self.ctx.reads, 2)
|
||||
|
||||
def test_all_comparison_operators(self):
|
||||
a, b = self._int(4), self._int(4)
|
||||
self.assertTrue(a == b)
|
||||
self.assertFalse(a != b)
|
||||
self.assertTrue(a <= b)
|
||||
self.assertTrue(a >= b)
|
||||
self.assertFalse(a < b)
|
||||
self.assertFalse(a > b)
|
||||
self.assertEqual(self.ctx.comparisons, 6)
|
||||
self.assertEqual(self.ctx.reads, 12)
|
||||
|
||||
def test_comparison_with_plain_int(self):
|
||||
a = self._int(5)
|
||||
result = a > 3 # 3 wird auto-gewrappt, kein extra Zähler
|
||||
self.assertTrue(result)
|
||||
self.assertEqual(self.ctx.comparisons, 1)
|
||||
self.assertEqual(self.ctx.reads, 2)
|
||||
|
||||
def test_eq_with_none_returns_false(self):
|
||||
a = self._int(1)
|
||||
self.assertFalse(a == None) # noqa: E711
|
||||
self.assertEqual(self.ctx.comparisons, 0) # keine Zählung
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Arithmetik (binär)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_addition_returns_new_int(self):
|
||||
a, b = self._int(3), self._int(4)
|
||||
c = a + b
|
||||
self.assertIsInstance(c, Int)
|
||||
self.assertEqual(c.value, 7)
|
||||
self.assertEqual(self.ctx.additions, 1)
|
||||
self.assertEqual(self.ctx.reads, 2)
|
||||
self.assertEqual(self.ctx.writes, 0)
|
||||
|
||||
def test_subtraction(self):
|
||||
a, b = self._int(10), self._int(4)
|
||||
c = a - b
|
||||
self.assertEqual(c.value, 6)
|
||||
self.assertEqual(self.ctx.subtractions, 1)
|
||||
|
||||
def test_multiplication(self):
|
||||
a, b = self._int(3), self._int(4)
|
||||
c = a * b
|
||||
self.assertEqual(c.value, 12)
|
||||
self.assertEqual(self.ctx.multiplications, 1)
|
||||
|
||||
def test_floordiv(self):
|
||||
a, b = self._int(10), self._int(3)
|
||||
c = a // b
|
||||
self.assertEqual(c.value, 3)
|
||||
self.assertEqual(self.ctx.divisions, 1)
|
||||
|
||||
def test_mod(self):
|
||||
a, b = self._int(10), self._int(3)
|
||||
c = a % b
|
||||
self.assertEqual(c.value, 1)
|
||||
self.assertEqual(self.ctx.divisions, 1)
|
||||
|
||||
def test_arithmetic_with_plain_int(self):
|
||||
a = self._int(5)
|
||||
c = a + 3
|
||||
self.assertEqual(c.value, 8)
|
||||
self.assertEqual(self.ctx.additions, 1)
|
||||
|
||||
def test_result_shares_context(self):
|
||||
a = self._int(5)
|
||||
b = self._int(3)
|
||||
c = a + b # c hat denselben ctx
|
||||
_ = c > self._int(0) # Vergleich auf c zählt im selben ctx
|
||||
self.assertEqual(self.ctx.comparisons, 1)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Augmented assignment
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_iadd_counts_read_add_write(self):
|
||||
a, b = self._int(5), self._int(3)
|
||||
a += b
|
||||
self.assertEqual(a.value, 8)
|
||||
self.assertEqual(self.ctx.reads, 2)
|
||||
self.assertEqual(self.ctx.additions, 1)
|
||||
self.assertEqual(self.ctx.writes, 1)
|
||||
|
||||
def test_isub(self):
|
||||
a, b = self._int(10), self._int(4)
|
||||
a -= b
|
||||
self.assertEqual(a.value, 6)
|
||||
self.assertEqual(self.ctx.subtractions, 1)
|
||||
self.assertEqual(self.ctx.writes, 1)
|
||||
|
||||
def test_imul(self):
|
||||
a, b = self._int(3), self._int(4)
|
||||
a *= b
|
||||
self.assertEqual(a.value, 12)
|
||||
self.assertEqual(self.ctx.multiplications, 1)
|
||||
self.assertEqual(self.ctx.writes, 1)
|
||||
|
||||
def test_iadd_with_plain_int(self):
|
||||
a = self._int(5)
|
||||
a += 1
|
||||
self.assertEqual(a.value, 6)
|
||||
self.assertEqual(self.ctx.writes, 1)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# set()
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_set_plain_counts_one_write(self):
|
||||
a = self._int(0)
|
||||
a.set(42)
|
||||
self.assertEqual(a.value, 42)
|
||||
self.assertEqual(self.ctx.writes, 1)
|
||||
self.assertEqual(self.ctx.reads, 0)
|
||||
|
||||
def test_set_int_counts_write_and_read(self):
|
||||
a = self._int(0)
|
||||
b = self._int(7)
|
||||
a.set(b)
|
||||
self.assertEqual(a.value, 7)
|
||||
self.assertEqual(self.ctx.writes, 1)
|
||||
self.assertEqual(self.ctx.reads, 1)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Typkonvertierung
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_int_conversion(self):
|
||||
a = self._int(5)
|
||||
self.assertEqual(int(a), 5)
|
||||
|
||||
def test_index_usage(self):
|
||||
a = self._int(2)
|
||||
lst = [10, 20, 30]
|
||||
self.assertEqual(lst[a], 30) # __index__
|
||||
|
||||
def test_hash(self):
|
||||
a = self._int(5)
|
||||
self.assertEqual(hash(a), hash(5))
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# AlgoContext.reset()
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def test_context_reset(self):
|
||||
a, b = self._int(3), self._int(4)
|
||||
_ = a > b
|
||||
self.ctx.reset()
|
||||
self.assertEqual(self.ctx.comparisons, 0)
|
||||
self.assertEqual(self.ctx.reads, 0)
|
||||
|
||||
|
||||
class TestIntNullCtx(unittest.TestCase):
|
||||
"""Int ohne expliziten ctx (irange-Verwendung) – keine Zählung."""
|
||||
|
||||
def test_arithmetic_without_ctx_produces_no_counts(self):
|
||||
from utils.algo_context import NULL_CTX
|
||||
a = Int(5) # uses NULL_CTX by default
|
||||
b = Int(3)
|
||||
_ = a + b
|
||||
_ = a > b
|
||||
# NULL_CTX hat feste 0-Attribute – keine Ausnahme, keine Zählung
|
||||
self.assertEqual(NULL_CTX.additions, 0)
|
||||
self.assertEqual(NULL_CTX.comparisons, 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@ -1,6 +1,6 @@
|
||||
import random
|
||||
import pygame
|
||||
from utils.game import Game
|
||||
from utils.algo_game import Game
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from bubble_sorting import bubble_sort_stepwise
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from utils.algo_range import irange
|
||||
from utils.algo_range import Range
|
||||
|
||||
|
||||
def bubble_sort_stepwise(z: Array, ctx: AlgoContext):
|
||||
@ -11,8 +11,8 @@ def bubble_sort_stepwise(z: Array, ctx: AlgoContext):
|
||||
Wird von bubble_game.py für die Visualisierung verwendet.
|
||||
"""
|
||||
n = len(z)
|
||||
for i in irange(n - 1):
|
||||
for j in irange(n - 1, i, -1):
|
||||
for i in Range(n - 1):
|
||||
for j in Range(n - 1, i, -1):
|
||||
if z[j - 1] > z[j]:
|
||||
z.swap(j - 1, j)
|
||||
yield z
|
||||
@ -27,7 +27,7 @@ def bubble_sort2_stepwise(z: Array, ctx: AlgoContext):
|
||||
n = len(z)
|
||||
while True:
|
||||
swapped = False
|
||||
for i in irange(n - 1):
|
||||
for i in Range(n - 1):
|
||||
if z[i] > z[i + 1]:
|
||||
z.swap(i, i + 1)
|
||||
swapped = True
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import random
|
||||
import pygame
|
||||
from utils.game import Game
|
||||
from utils.algo_game import Game
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from insert_sorting import insert_sort_stepwise
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from utils.algo_int import Int
|
||||
from utils.algo_range import irange
|
||||
from utils.algo_range import Range
|
||||
|
||||
|
||||
def insert_sort_stepwise(z: Array, ctx: AlgoContext):
|
||||
@ -13,7 +13,7 @@ def insert_sort_stepwise(z: Array, ctx: AlgoContext):
|
||||
n = len(z)
|
||||
elem = Int(0, ctx) # Zwischenregister für das einzufügende Element
|
||||
|
||||
for i in irange(n):
|
||||
for i in Range(n):
|
||||
elem.set(z[i]) # 1 read + 1 write
|
||||
j = Int(int(i), ctx)
|
||||
while j > 0 and z[j - 1] > elem:
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import random
|
||||
import pygame
|
||||
from utils.game import Game
|
||||
from utils.algo_game import Game
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from select_sorting import select_sort_stepwise
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from utils.algo_int import Int
|
||||
from utils.algo_range import irange
|
||||
from utils.algo_range import Range
|
||||
|
||||
|
||||
def select_sort_stepwise(z: Array, ctx: AlgoContext):
|
||||
@ -13,9 +13,9 @@ def select_sort_stepwise(z: Array, ctx: AlgoContext):
|
||||
n = len(z)
|
||||
cur_min = Int(0, ctx) # Index des aktuellen Minimums
|
||||
|
||||
for i in irange(n):
|
||||
for i in Range(n):
|
||||
cur_min.set(Int(int(i), ctx))
|
||||
for j in irange(int(i) + 1, n):
|
||||
for j in Range(int(i) + 1, n):
|
||||
if z[j] < z[cur_min]:
|
||||
cur_min.set(Int(int(j), ctx))
|
||||
z.swap(int(i), int(cur_min))
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import random
|
||||
import pygame
|
||||
from utils.game import Game
|
||||
from utils.algo_game import Game
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from heap_sorting import heap_sort_stepwise
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import random
|
||||
import pygame
|
||||
from utils.game import Game
|
||||
from utils.algo_game import Game
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from quick_sorting import quick_sort_stepwise
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from utils.algo_range import irange
|
||||
from utils.algo_range import Range
|
||||
|
||||
|
||||
def count_sort(a: Array, b: Array, k: int, ctx: AlgoContext):
|
||||
@ -14,15 +14,15 @@ def count_sort(a: Array, b: Array, k: int, ctx: AlgoContext):
|
||||
c = Array([0] * (k + 1), ctx) # Zählarray
|
||||
|
||||
# Häufigkeiten zählen
|
||||
for j in irange(len(a)):
|
||||
for j in Range(len(a)):
|
||||
c[a[j]] = c[a[j]] + 1
|
||||
|
||||
# Kumulierte Summen bilden
|
||||
for i in irange(1, k + 1):
|
||||
for i in Range(1, k + 1):
|
||||
c[i] = c[i] + c[i - 1]
|
||||
|
||||
# Stabil in b einsortieren (rückwärts für Stabilität)
|
||||
for j in irange(len(a) - 1, -1, -1):
|
||||
for j in Range(len(a) - 1, -1, -1):
|
||||
b[c[a[j]] - 1] = a[j]
|
||||
c[a[j]] = c[a[j]] - 1
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import random
|
||||
import pygame
|
||||
from utils.game import Game
|
||||
from utils.algo_game import Game
|
||||
from utils.algo_context import AlgoContext
|
||||
from avl_tree import AVLTree
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
from vorlesung.L05_binaere_baeume.bin_tree_node import BinaryTreeNode
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.project_dir import get_path
|
||||
from utils.algo_path import path
|
||||
from datetime import datetime
|
||||
import graphviz
|
||||
|
||||
@ -148,7 +148,7 @@ class BinaryTree:
|
||||
self.tree_structure_traversal(define_node)
|
||||
_rec(self.root)
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
dot.render(get_path(f"{self.graph_filename()}_{timestamp}.gv"))
|
||||
dot.render(path(f"{self.graph_filename()}_{timestamp}.gv"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import random
|
||||
import pygame
|
||||
from utils.game import Game
|
||||
from utils.algo_game import Game
|
||||
from utils.algo_context import AlgoContext
|
||||
from bin_tree import BinaryTree
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ from collections.abc import Callable
|
||||
from utils.algo_context import AlgoContext
|
||||
from utils.algo_array import Array
|
||||
from utils.algo_int import Int
|
||||
from utils.algo_range import irange
|
||||
from utils.algo_range import Range
|
||||
|
||||
|
||||
UNUSED_MARK = "UNUSED"
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
from vorlesung.L08_graphen.graph import Graph, AdjacencyMatrixGraph
|
||||
from utils.project_dir import get_path
|
||||
|
||||
graph = AdjacencyMatrixGraph()
|
||||
start = ""
|
||||
end = ""
|
||||
|
||||
def read_file(filename: str = "data/aoc2212.txt"):
|
||||
"""Read a file and return the content as a string."""
|
||||
|
||||
def adjust_char(char):
|
||||
"""Adjust character for comparison."""
|
||||
if char == 'S':
|
||||
return 'a'
|
||||
elif char == 'E':
|
||||
return 'z'
|
||||
return char
|
||||
|
||||
global start, end
|
||||
with open(get_path(filename), "r") as file:
|
||||
quest = file.read().strip().splitlines()
|
||||
for row, line in enumerate(quest):
|
||||
for col, char in enumerate(line):
|
||||
label = f"{row},{col}"
|
||||
graph.insert_vertex(label)
|
||||
if char == "S":
|
||||
start = label
|
||||
if char == "E":
|
||||
end = label
|
||||
for row, line in enumerate(quest):
|
||||
for col, char in enumerate(line):
|
||||
for neighbor in [(row - 1, col), (row, col - 1), (row + 1, col), (row, col + 1)]:
|
||||
if 0 <= neighbor[0] < len(quest) and 0 <= neighbor[1] < len(line):
|
||||
if ord(adjust_char(quest[neighbor[0]][neighbor[1]])) <= ord(adjust_char(char)) + 1:
|
||||
label1 = f"{row},{col}"
|
||||
label2 = f"{neighbor[0]},{neighbor[1]}"
|
||||
graph.connect(label1, label2)
|
||||
|
||||
|
||||
# Lösung des Adventskalenders 2022, Tag 12
|
||||
read_file("data/aoc2212test.txt")
|
||||
graph.graph()
|
||||
distance_map, predecessor_map = graph.bfs(start)
|
||||
print(distance_map[graph.get_vertex(end)])
|
||||
print(graph.path(end, predecessor_map))
|
||||
@ -5,8 +5,8 @@ import graphviz
|
||||
import math
|
||||
import heapq
|
||||
from datetime import datetime
|
||||
from utils.project_dir import get_path
|
||||
from utils.priority_queue import PriorityQueue
|
||||
from utils.algo_path import path
|
||||
from utils.algo_priority_queue import PriorityQueue
|
||||
from vorlesung.L09_mst.disjoint import DisjointValue
|
||||
|
||||
|
||||
@ -155,7 +155,7 @@ class Graph:
|
||||
dot.edge(str(id(self.get_vertex(edge[0]))), str(id(self.get_vertex(edge[1]))), label=str(edge[2]))
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"{filename}_{timestamp}.gv"
|
||||
filename = get_path(filename)
|
||||
filename = path(filename)
|
||||
dot.render(filename)
|
||||
|
||||
def dijkstra(self, start_name: str) -> tuple[dict[Vertex, float], dict[Vertex, Vertex | None]]:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user