diff --git a/bigjoyints/divmod.py b/bigjoyints/divmod.py index 9466696..8231968 100644 --- a/bigjoyints/divmod.py +++ b/bigjoyints/divmod.py @@ -16,22 +16,39 @@ def div_mod(A, B): if not B: raise ZeroDivisionError() a_len, b_len = len(A), len(B) - if a_len < b_len or A[-1] < B[-1]: + if a_len < b_len or (a_len == b_len and A[-1] < B[-1]): return [], A # Whew! Okay, we got all that out of the way. # A > B - A_digits = A[-b_len:] + A, A_digits = A[:-b_len], A[-b_len:] if -1 == cmp_digits(A_digits, B): # Because we know # A > B AND a_len >= b_len (aka len(A_digits)) # if A_digits < B there must be at least one more # digit in A: assert a_len > b_len - A_digits = A[-(b_len + 1):] + A_digits.insert(0, A.pop()) assert -1 < cmp_digits(A_digits, B) - q, r = lil_divmod(A_digits, B) + q, R = lil_divmod(A_digits, B) + # So we have divided a prefix of A by B + # resulting in a digit q of the answer Q + # and a remainder R that must be extended + # with the rest of the digits of A to make + # a new number N + + N = A + R + + # which then must either be the remainder of + # the whole thing if N < B... + if -1 == cmp_digits(N, B): + return [q], N + # Otherwise, we find the rest of the digits + # by + Q, R = div_mod(N, B) + Q.append(digit) + return Q, R def lil_divmod(A, B): assert -1 < cmp_digits(A, B) @@ -60,6 +77,7 @@ def int_to_list(i): return list(map(int, str(i)[::-1])) def list_to_int(A): + if not A: return 0 i = int(''.join(map(str, A[::-1]))) assert i >= 0 return i @@ -88,9 +106,19 @@ def subtract(A, B): A = int_to_list(145) B = int_to_list(72) -q, R = lil_divmod(A, B) -print(f'divmod({list_to_int(A)}, {list_to_int(B)}) = ', - q, list_to_int(R)) + +##q, R = lil_divmod(A, B) +##print(f'divmod({list_to_int(A)}, {list_to_int(B)}) = ', +## q, list_to_int(R)) + +def try_it(a, b): + A = int_to_list(a) + B = int_to_list(b) + Q, R = div_mod(A, B) + print(f'divmod({list_to_int(A)}, {list_to_int(B)}) = {list_to_int(Q)}, {list_to_int(R)}') + +try_it(145, 72) +try_it(1450, 72) ##print(cmp_digits([], []))