Task 10 exercise a

This commit is contained in:
Jan-Niclas Loosen
2026-01-26 22:40:07 +01:00
parent 90ce78f17d
commit b8a2972b6b
5 changed files with 392 additions and 1 deletions

59
Uebung-03/find.py Normal file
View File

@@ -0,0 +1,59 @@
import math
import random
from multiprocessing import Pool
from typing import Optional, Iterable, Tuple
def gen_nums(n: int) -> list[int]:
assert n > 0
nums = list(range(2 ** n))
random.shuffle(nums)
return nums
def chunks(n: int, p: int) -> Iterable[Tuple[int, int]]:
base, rem = divmod(n, p)
start = 0
for i in range(p):
size = base + (1 if i < rem else 0)
end = start + size
yield start, end
start = end
def t_find(args: Tuple[int, int, list[int], int]) -> Optional[int]:
s, e, haystack, needle = args
for i in range(s, e):
if haystack[i] == needle:
return i
return None
def find(needle: int, haystack: list[int]) -> Optional[int]:
size = len(haystack)
assert size >= 1
procs = int(math.log2(size))
ranges = list(chunks(size, procs))
with Pool(processes=procs) as pool:
res = pool.map(t_find, [(s, e, haystack, needle) for (s, e) in ranges])
for idx in res:
if idx is not None:
return idx
return None
def fuzz_test(trials: int = 200, max_n: int = 16, seed: Optional[int] = None) -> None:
if seed is not None:
random.seed(seed)
for t in range(1, trials + 1):
n = random.randint(1, max_n)
arr = gen_nums(n)
idx_true = random.randrange(len(arr))
needle = arr[idx_true]
expected = idx_true
got = find(needle, arr)
assert got == expected, f"[t={t}] Expected {expected}, got {got}; n={n}"
print(f"Fuzz OK: {trials} trials, max_n={max_n}")
fuzz_test(trials=1000, max_n=16)