#!/usr/bin/env python3 # -*- coding: utf-8 -*- # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # IMPORTS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ from src.thirdparty.types import *; from src.thirdparty.maths import *; from models.generated.config import *; from src.core.utils import *; from src.models.euklid import *; from src.algorithms.euklid.display import *; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # EXPORTS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __all__ = [ 'euklidean_algorithm', ]; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # METHOD euklidean algorithm # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def euklidean_algorithm( a: int, b: int, verbose: bool = False, ) -> Tuple[int, int, int]: ''' Führt den Euklideschen Algorithmus aus, um den größten gemeinsamen Teiler (ggT, en: gcd) von zwei positiven Zahlen zu berechnen. ''' ################ # NOTE: # Lemma: gcd(a,b) = gcd(mod(a, b), b) # Darum immer weiter (a, b) durch (b, gcd(a,b)) ersetzen, bis b == 0. ################ steps = []; d = 0; while True: if b == 0: d = a; steps.append(Step(a=a, b=b, gcd=d, div=0, rem=a, coeff_a=1, coeff_b=0)); break; else: # Berechne k, r so dass a = k·b + r mit k ≥ 0, 0 ≤ r < b: r = a % b; k = math.floor(a / b); # Speichere Berechnungen: steps.append(Step(a=a, b=b, gcd=0, div=k, rem=r, coeff_a=0, coeff_b=0)); # ersetze a, b durch b, r: a = b; b = r; ################ # NOTE: # In jedem step gilt # a = k·b + r # und im folgenden gilt: # d = coeff_a'·a' + coeff_b'·b' # wobei # a' = b # b' = r # Darum: # d = coeff_a'·b + coeff_b'·(a - k·b) # = coeff_b'·a + (coeff_a' - k·coeff_b)·b # Darum: # coeff_a = coeff_b' # coeff_b = coeff_a' - k·coeff_b ################ coeff_a = 1; coeff_b = 0; for step in steps[::-1][1:]: (coeff_a, coeff_b) = (coeff_b, coeff_a - step.div * coeff_b); step.coeff_a = coeff_a; step.coeff_b = coeff_b; step.gcd = d; if verbose: step = steps[0]; repr = display_table(steps=steps, reverse=True); expr = display_sum(step=step); print(''); print('\x1b[1mEuklidescher Algorithmus\x1b[0m'); print(''); print(repr); print(''); print('\x1b[1mLösung\x1b[0m'); print(''); print(f'a=\x1b[1m{step.a}\x1b[0m; b=\x1b[1m{step.b}\x1b[0m; d = \x1b[1m{step.gcd}\x1b[0m = {expr}.'); print(''); return d, coeff_a, coeff_b;