fork(1) download
  1. # Add internal numeric base (4)
  2. # @see kuVRVb
  3.  
  4. import itertools
  5. import operator
  6.  
  7. class Num:
  8. base = 2**8
  9.  
  10. def __init__(self, init=0):
  11. if isinstance(init, tuple):
  12. self.m = init[0].copy()
  13. self.s = init[1]
  14. else:
  15. self.m = iton(abs(init), Num.base)
  16. self.s = init < 0
  17.  
  18. def __neg__(self):
  19. return Num((self.m, not self.s))
  20.  
  21. def __add__(self, other):
  22. return Num(nadd(self.m, self.s, other.m, other.s, Num.base))
  23.  
  24. def __sub__(self, other):
  25. return Num(nadd(self.m, self.s, other.m, not other.s, Num.base))
  26.  
  27. def __mul__(self, other):
  28. return Num(nmul(self.m, self.s, other.m, other.s, Num.base))
  29.  
  30. def __str__(self):
  31. return '-' * self.s + ntos(self.m, Num.base)
  32.  
  33. def __repr__(self):
  34. return str((self.m, self.s))
  35.  
  36. # Utility.
  37.  
  38. def _fixsign(a, s):
  39. return a, False if _iszero(a) else s
  40.  
  41. def _iszero(a):
  42. return len(a) == 1 and a[0] == 0
  43.  
  44. def _zeroextend(a, n):
  45. return a[:] + [0] * (n - len(a))
  46.  
  47. def _zeroreduce(a):
  48. n = len(a)
  49. while n != 1 and a[n-1] == 0:
  50. n -= 1
  51. return a[:n]
  52.  
  53. # Convert.
  54.  
  55. def iton(x, b):
  56. r = []
  57. while True:
  58. x, y = divmod(x, b)
  59. r.append(y)
  60. if x == 0:
  61. return r
  62.  
  63. def nton(a, bi, bo):
  64. r = [0]
  65. for x in reversed(a):
  66. for i in range(len(r)):
  67. x, r[i] = divmod(r[i] * bi + x, bo)
  68. if x != 0:
  69. r.extend(iton(x, bo))
  70. return r
  71.  
  72. def ntos(a, b):
  73. return ''.join(map(str, reversed(nton(a, b, 10))))
  74.  
  75. # Compare.
  76.  
  77. def _cmp(x, y):
  78. if x != y:
  79. return -1 if x < y else 1
  80. return 0
  81.  
  82. def ncmp(a, b):
  83. n = len(a)
  84. m = len(b)
  85. u = itertools.chain([n], reversed(a))
  86. v = itertools.chain([m], reversed(b))
  87. return next(itertools.dropwhile(lambda x: x == 0, map(_cmp, u, v)), 0)
  88.  
  89. # Shift.
  90.  
  91. def nshl(a, n):
  92. return _zeroreduce([0] * n + a[:])
  93.  
  94. def nshr(a, n):
  95. return _zeroextend(a[n:], 1)
  96.  
  97. # Add.
  98.  
  99. def _add(a, b, base, op):
  100. n = 1 + max(len(a), len(b))
  101. r = _zeroextend(a, n)
  102. b = _zeroextend(b, n)
  103. c = 0
  104. for i in range(n):
  105. c, r[i] = divmod(op(r[i], b[i] + abs(c)), base)
  106. return _zeroreduce(r)
  107.  
  108. def nadd(a, s, b, t, base):
  109. if s == t:
  110. return _fixsign(_add(a, b, base, operator.add), s)
  111. elif ncmp(a, b) < 0:
  112. return _fixsign(_add(b, a, base, operator.sub), t)
  113. else:
  114. return _fixsign(_add(a, b, base, operator.sub), s)
  115.  
  116. # Multiply.
  117.  
  118. def _mul1(a, x, base):
  119. n = 1 + len(a)
  120. r = _zeroextend(a, n)
  121. c = 0
  122. for i in range(n):
  123. c, r[i] = divmod(r[i] * x + c, base)
  124. return _zeroreduce(r)
  125.  
  126. def _mul(a, b, base):
  127. if _iszero(b):
  128. return [0]
  129. return _add(_mul1(a, b[0], base), _mul(nshl(a, 1), nshr(b, 1), base),
  130. base, operator.add)
  131.  
  132. def nmul(a, s, b, t, base):
  133. return _fixsign(_mul(a, b, base), s != t)
  134.  
  135. # Test.
  136.  
  137. def _test(n, op):
  138. for x, y in itertools.product(range(-n, n+1), repeat=2):
  139. u = int(str(op(Num(x), Num(y))))
  140. v = op(x, y)
  141. assert u == v, f'{op}({x}, {y})\nExpected:{v}, Got:{u}'
  142.  
  143. n = 50
  144. _test(n, operator.add)
  145. _test(n, operator.sub)
  146. _test(n, operator.mul)
  147.  
  148. def factorial(n):
  149. r = Num(1)
  150. for i in range(2, n+1):
  151. r *= Num(i)
  152. return r
  153.  
  154. def show(a):
  155. print(repr(a), a, sep='; ')
  156.  
  157. x = 12345
  158. z = (0, 1, -1, x, -x)
  159. for x in z:
  160. show(Num(x))
  161. print('+')
  162. for x, y in itertools.product(z, repeat=2):
  163. show(Num(x) + Num(y))
  164. print('-')
  165. for x, y in itertools.product(z, repeat=2):
  166. show(Num(x) - Num(y))
  167. print('*')
  168. for x, y in itertools.product(z, repeat=2):
  169. show(Num(x) * Num(y))
  170. print('f')
  171. for i in range(5):
  172. show(factorial(10*i))
Success #stdin #stdout 0.46s 10192KB
stdin
Standard input is empty
stdout
([0], False); 0
([1], False); 1
([1], True); -1
([57, 48], False); 12345
([57, 48], True); -12345
+
([0], False); 0
([1], False); 1
([1], True); -1
([57, 48], False); 12345
([57, 48], True); -12345
([1], False); 1
([2], False); 2
([0], False); 0
([58, 48], False); 12346
([56, 48], True); -12344
([1], True); -1
([0], False); 0
([2], True); -2
([56, 48], False); 12344
([58, 48], True); -12346
([57, 48], False); 12345
([58, 48], False); 12346
([56, 48], False); 12344
([114, 96], False); 24690
([0], False); 0
([57, 48], True); -12345
([56, 48], True); -12344
([58, 48], True); -12346
([0], False); 0
([114, 96], True); -24690
-
([0], False); 0
([1], True); -1
([1], False); 1
([57, 48], True); -12345
([57, 48], False); 12345
([1], False); 1
([0], False); 0
([2], False); 2
([56, 48], True); -12344
([58, 48], False); 12346
([1], True); -1
([2], True); -2
([0], False); 0
([58, 48], True); -12346
([56, 48], False); 12344
([57, 48], False); 12345
([56, 48], False); 12344
([58, 48], False); 12346
([0], False); 0
([114, 96], False); 24690
([57, 48], True); -12345
([58, 48], True); -12346
([56, 48], True); -12344
([114, 96], True); -24690
([0], False); 0
*
([0], False); 0
([0], False); 0
([0], False); 0
([0], False); 0
([0], False); 0
([0], False); 0
([1], False); 1
([1], True); -1
([57, 48], False); 12345
([57, 48], True); -12345
([0], False); 0
([1], True); -1
([1], False); 1
([57, 48], True); -12345
([57, 48], False); 12345
([0], False); 0
([57, 48], False); 12345
([57, 48], True); -12345
([177, 108, 21, 9], False); 152399025
([177, 108, 21, 9], True); -152399025
([0], False); 0
([57, 48], True); -12345
([57, 48], False); 12345
([177, 108, 21, 9], True); -152399025
([177, 108, 21, 9], False); 152399025
f
([1], False); 1
([0, 95, 55], False); 3628800
([0, 0, 180, 130, 124, 103, 195, 33], False); 2432902008176640000
([0, 0, 0, 84, 221, 245, 93, 134, 150, 15, 55, 246, 19, 13], False); 265252859812191058636308480000000
([0, 0, 0, 0, 64, 37, 5, 255, 100, 222, 15, 8, 126, 242, 199, 132, 27, 232, 234, 142], False); 815915283247897734345611269596115894272000000000