# Variation on multiply (2).
# @see bOJ7Zy
# Conversion.
def iton(x):
r = []
while True:
x, y = divmod(x, 10)
r.append(y)
if x == 0:
return r
def ntos(a):
return ''.join(map(str, reversed(a)))
# Math.
def _iszero(a):
return len(a) == 1 and a[0] == 0
def _zeroextend(a, n):
return a[:] + [0] * (n - len(a))
def _zeroreduce(a):
n = len(a)
while n != 1 and a[n-1] == 0:
n -= 1
return a[:n]
def nshl(a, n):
return _zeroreduce([0] * n + a[:])
def nshr(a, n):
return _zeroextend(a[n:], 1)
def nadd(a, b):
n = 1 + max(len(a), len(b))
r = _zeroextend(a, n)
b = _zeroextend(b, n)
c = 0
for i in range(n):
c, r[i] = divmod(r[i] + b[i] + c, 10)
return _zeroreduce(r)
def _mul1(a, x):
assert 0 <= x < 10
n = 1 + len(a)
r = _zeroextend(a, n)
c = 0
for i in range(n):
c, r[i] = divmod(r[i] * x + c, 10)
return _zeroreduce(r)
def nmul(a, b):
if _iszero(b):
return [0]
return nadd(_mul1(a, b[0]), nmul(nshl(a, 1), nshr(b, 1)))
# Test.
n = 50
for x in range(0, n+1):
for y in range(0, n+1):
# nadd
u = int(ntos(nadd(iton(x), iton(y))))
v = x + y
assert u == v, f'{x} + {y}; {u}, {v}'
# nmul
u = int(ntos(nmul(iton(x), iton(y))))
v = x * y
assert u == v, f'{x} * {y}; {u}, {v}'
def show(y):
return y, ntos(y)
x = 123
print(show(iton(0)))
print(show(iton(1)))
print(show(iton(x)))
print('-')
print(show(nadd(iton(0), iton(0))))
print(show(nadd(iton(1), iton(1))))
print(show(nadd(iton(x), iton(x))))
print('-')
print(show(nmul(iton(0), iton(0))))
print(show(nmul(iton(0), iton(1))))
print(show(nmul(iton(1), iton(0))))
print(show(nmul(iton(1), iton(1))))
print(show(nmul(iton(x), iton(1))))
print(show(nmul(iton(1), iton(x))))
print(show(nmul(iton(x), iton(x))))
print(show(nmul(iton(x), iton(x*x))))
print(show(nmul(iton(x*x), iton(x))))
IyBWYXJpYXRpb24gb24gbXVsdGlwbHkgKDIpLgojIEBzZWUgYk9KN1p5CgojIENvbnZlcnNpb24uCgpkZWYgaXRvbih4KToKICAgIHIgPSBbXQogICAgd2hpbGUgVHJ1ZToKICAgICAgICB4LCB5ID0gZGl2bW9kKHgsIDEwKQogICAgICAgIHIuYXBwZW5kKHkpCiAgICAgICAgaWYgeCA9PSAwOgogICAgICAgICAgICByZXR1cm4gcgoKZGVmIG50b3MoYSk6CiAgICByZXR1cm4gJycuam9pbihtYXAoc3RyLCByZXZlcnNlZChhKSkpCgojIE1hdGguCgpkZWYgX2lzemVybyhhKToKICAgIHJldHVybiBsZW4oYSkgPT0gMSBhbmQgYVswXSA9PSAwCgpkZWYgX3plcm9leHRlbmQoYSwgbik6CiAgICByZXR1cm4gYVs6XSArIFswXSAqIChuIC0gbGVuKGEpKQoKZGVmIF96ZXJvcmVkdWNlKGEpOgogICAgbiA9IGxlbihhKQogICAgd2hpbGUgbiAhPSAxIGFuZCBhW24tMV0gPT0gMDoKICAgICAgICBuIC09IDEKICAgIHJldHVybiBhWzpuXQoKZGVmIG5zaGwoYSwgbik6CiAgICByZXR1cm4gX3plcm9yZWR1Y2UoWzBdICogbiArIGFbOl0pCgpkZWYgbnNocihhLCBuKToKICAgIHJldHVybiBfemVyb2V4dGVuZChhW246XSwgMSkKCmRlZiBuYWRkKGEsIGIpOgogICAgbiA9IDEgKyBtYXgobGVuKGEpLCBsZW4oYikpCiAgICByID0gX3plcm9leHRlbmQoYSwgbikKICAgIGIgPSBfemVyb2V4dGVuZChiLCBuKQogICAgYyA9IDAKICAgIGZvciBpIGluIHJhbmdlKG4pOgogICAgICAgIGMsIHJbaV0gPSBkaXZtb2QocltpXSArIGJbaV0gKyBjLCAxMCkKICAgIHJldHVybiBfemVyb3JlZHVjZShyKQoKZGVmIF9tdWwxKGEsIHgpOgogICAgYXNzZXJ0IDAgPD0geCA8IDEwCiAgICBuID0gMSArIGxlbihhKQogICAgciA9IF96ZXJvZXh0ZW5kKGEsIG4pCiAgICBjID0gMAogICAgZm9yIGkgaW4gcmFuZ2Uobik6CiAgICAgICAgYywgcltpXSA9IGRpdm1vZChyW2ldICogeCArIGMsIDEwKQogICAgcmV0dXJuIF96ZXJvcmVkdWNlKHIpCgpkZWYgbm11bChhLCBiKToKICAgIGlmIF9pc3plcm8oYik6CiAgICAgICAgcmV0dXJuIFswXQogICAgcmV0dXJuIG5hZGQoX211bDEoYSwgYlswXSksIG5tdWwobnNobChhLCAxKSwgbnNocihiLCAxKSkpCgojIFRlc3QuCgpuID0gNTAKZm9yIHggaW4gcmFuZ2UoMCwgbisxKToKICAgIGZvciB5IGluIHJhbmdlKDAsIG4rMSk6CiAgICAgICAgIyBuYWRkCiAgICAgICAgdSA9IGludChudG9zKG5hZGQoaXRvbih4KSwgaXRvbih5KSkpKQogICAgICAgIHYgPSB4ICsgeQogICAgICAgIGFzc2VydCB1ID09IHYsIGYne3h9ICsge3l9OyB7dX0sIHt2fScKICAgICAgICAjIG5tdWwKICAgICAgICB1ID0gaW50KG50b3Mobm11bChpdG9uKHgpLCBpdG9uKHkpKSkpCiAgICAgICAgdiA9IHggKiB5CiAgICAgICAgYXNzZXJ0IHUgPT0gdiwgZid7eH0gKiB7eX07IHt1fSwge3Z9JwoKZGVmIHNob3coeSk6CiAgICByZXR1cm4geSwgbnRvcyh5KQoKeCA9IDEyMwpwcmludChzaG93KGl0b24oMCkpKQpwcmludChzaG93KGl0b24oMSkpKQpwcmludChzaG93KGl0b24oeCkpKQpwcmludCgnLScpCnByaW50KHNob3cobmFkZChpdG9uKDApLCBpdG9uKDApKSkpCnByaW50KHNob3cobmFkZChpdG9uKDEpLCBpdG9uKDEpKSkpCnByaW50KHNob3cobmFkZChpdG9uKHgpLCBpdG9uKHgpKSkpCnByaW50KCctJykKcHJpbnQoc2hvdyhubXVsKGl0b24oMCksIGl0b24oMCkpKSkKcHJpbnQoc2hvdyhubXVsKGl0b24oMCksIGl0b24oMSkpKSkKcHJpbnQoc2hvdyhubXVsKGl0b24oMSksIGl0b24oMCkpKSkKcHJpbnQoc2hvdyhubXVsKGl0b24oMSksIGl0b24oMSkpKSkKcHJpbnQoc2hvdyhubXVsKGl0b24oeCksIGl0b24oMSkpKSkKcHJpbnQoc2hvdyhubXVsKGl0b24oMSksIGl0b24oeCkpKSkKcHJpbnQoc2hvdyhubXVsKGl0b24oeCksIGl0b24oeCkpKSkKcHJpbnQoc2hvdyhubXVsKGl0b24oeCksIGl0b24oeCp4KSkpKQpwcmludChzaG93KG5tdWwoaXRvbih4KngpLCBpdG9uKHgpKSkp
([0], '0')
([1], '1')
([3, 2, 1], '123')
-
([0], '0')
([2], '2')
([6, 4, 2], '246')
-
([0], '0')
([0], '0')
([0], '0')
([1], '1')
([3, 2, 1], '123')
([3, 2, 1], '123')
([9, 2, 1, 5, 1], '15129')
([7, 6, 8, 0, 6, 8, 1], '1860867')
([7, 6, 8, 0, 6, 8, 1], '1860867')