Almost got it...

This commit is contained in:
Simon Forman 2022-10-05 08:49:35 -07:00
parent 70ea2c3f53
commit 0ee3d00537
1 changed files with 35 additions and 7 deletions

View File

@ -16,22 +16,39 @@ def div_mod(A, B):
if not B: if not B:
raise ZeroDivisionError() raise ZeroDivisionError()
a_len, b_len = len(A), len(B) 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 return [], A
# Whew! Okay, we got all that out of the way. # Whew! Okay, we got all that out of the way.
# A > B # A > B
A_digits = A[-b_len:] A, A_digits = A[:-b_len], A[-b_len:]
if -1 == cmp_digits(A_digits, B): if -1 == cmp_digits(A_digits, B):
# Because we know # Because we know
# A > B AND a_len >= b_len (aka len(A_digits)) # A > B AND a_len >= b_len (aka len(A_digits))
# if A_digits < B there must be at least one more # if A_digits < B there must be at least one more
# digit in A: # digit in A:
assert a_len > b_len assert a_len > b_len
A_digits = A[-(b_len + 1):] A_digits.insert(0, A.pop())
assert -1 < cmp_digits(A_digits, B) 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): def lil_divmod(A, B):
assert -1 < cmp_digits(A, B) assert -1 < cmp_digits(A, B)
@ -60,6 +77,7 @@ def int_to_list(i):
return list(map(int, str(i)[::-1])) return list(map(int, str(i)[::-1]))
def list_to_int(A): def list_to_int(A):
if not A: return 0
i = int(''.join(map(str, A[::-1]))) i = int(''.join(map(str, A[::-1])))
assert i >= 0 assert i >= 0
return i return i
@ -88,9 +106,19 @@ def subtract(A, B):
A = int_to_list(145) A = int_to_list(145)
B = int_to_list(72) B = int_to_list(72)
q, R = lil_divmod(A, B)
print(f'divmod({list_to_int(A)}, {list_to_int(B)}) = ', ##q, R = lil_divmod(A, B)
q, list_to_int(R)) ##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([], [])) ##print(cmp_digits([], []))