21_monkeymath.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. #!/usr/bin/env python3
  2. import sys
  3. from operator import mul, floordiv, add, sub
  4. class Expr:
  5. def __init__(self, left, op, right):
  6. self.left = left
  7. self.op = op
  8. self.right = right
  9. def __str__(self):
  10. return '(%s %s %s)' % (self.left, self.op, self.right)
  11. def simplify(expr, solve=None):
  12. if isinstance(expr, (int, str)):
  13. return expr
  14. left = simplify(expr.left)
  15. right = simplify(expr.right)
  16. if isinstance(left, int) and isinstance(right, int):
  17. fn = {'*': mul, '/': floordiv, '-': sub, '+': add}[expr.op]
  18. return fn(left, right)
  19. if isinstance(left, int) and expr.op in '*+':
  20. return simplify(Expr(right, expr.op, left))
  21. if expr.op == '=' and isinstance(left, Expr):
  22. if isinstance(left.right, int):
  23. inv = {'*': '/', '/': '*', '-': '+', '+': '-'}[left.op]
  24. return simplify(Expr(left.left, '=', Expr(right, inv, left.right)))
  25. if isinstance(left.left, int) and left.op == '-':
  26. return simplify(Expr(left.right, '=', Expr(left.left, '-', right)))
  27. if expr.op == '=' and left == solve:
  28. return right
  29. return Expr(left, expr.op, right)
  30. def parse(tasks, monkey):
  31. task = tasks[monkey]
  32. if ' ' in task:
  33. left, op, right = task.split()
  34. return Expr(parse(tasks, left), op, parse(tasks, right))
  35. return int(task) if task.isdigit() else task
  36. tasks = dict(line.rstrip().split(': ') for line in sys.stdin)
  37. print(simplify(parse(tasks, 'root')))
  38. tasks['humn'] = 'humn'
  39. left, _, right = tasks['root'].split()
  40. tasks['root'] = left + ' = ' + right
  41. print(simplify(parse(tasks, 'root')))