fork download
  1. import string, re
  2. DIGITS = string.digits + string.ascii_uppercase
  3.  
  4. def check_base(base):
  5. if not isinstance(base, int) or not 2 <= base <= 36: raise ValueError(f"Неверное основание: {base!r}.")
  6.  
  7. def to_base(n, base):
  8. check_base(base)
  9. result = ""
  10. while True:
  11. result = DIGITS[n % base] + result
  12. n //= base
  13. if n == 0: break
  14. return result
  15.  
  16. def from_base(sn, base):
  17. check_base(base)
  18. result, multiplier = 0, 1
  19. for sdig in reversed(sn):
  20. if '0' <= sdig <= '9': digit = ord(sdig) - ord('0')
  21. elif 'A' <= sdig <= 'Z': digit = ord(sdig) - ord('A') + 10
  22. elif 'a' <= sdig <= 'z': digit = ord(sdig) - ord('a') + 10
  23. else: digit = None
  24. if digit is None or digit >= base: raise ValueError(f"Неверный {base}-разряд: {sdig!r}.")
  25. result += multiplier * digit
  26. multiplier *= base
  27. return result
  28.  
  29. input_re = re.compile("""
  30. \s* (?P<inp_value> [0-9A-Z]+)
  31. (
  32. \s* \( (?P<inp_base> \d+) \)
  33. )?
  34. (
  35. \s* -> \s* (?P<target_base> \d+)
  36. )?
  37. \s*""", re.VERBOSE)
  38.  
  39. match = input_re.fullmatch(input("Введите запрос, например, FF(16)->2: "))
  40. if match:
  41. inp_value, inp_base, target_base = match['inp_value'], match['inp_base'], match['target_base']
  42. inp_basev, target_basev = inp_base and int(inp_base), target_base and int(target_base)
  43. if inp_base is None: inp_basev = 16 if target_basev == 10 else 10
  44. if target_base is None: target_basev = 16 if inp_basev == 10 else 10
  45.  
  46. result = to_base(from_base(inp_value, inp_basev), target_basev)
  47. print(f"\n{inp_value}({inp_basev}) = {result}({target_basev})")
  48. else:
  49. print("Не понял.")
Success #stdin #stdout 0.03s 9556KB
stdin
11111110(2)->16
stdout
Введите запрос, например, FF(16)->2: 
11111110(2) = FE(16)