07_logicgates.py 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #!/usr/bin/env python3
  2. import sys
  3. from operator import and_, or_, lshift, rshift, inv
  4. opmap = {'AND': and_, 'OR': or_, 'LSHIFT': lshift,
  5. 'RSHIFT': rshift, 'NOT': inv}
  6. WIRE, UNARY, BINARY, CONST = range(4)
  7. imax = 1 << 16
  8. wires = {}
  9. def wrap(val):
  10. return (CONST, int(val)) if val.isdigit() else (WIRE, val)
  11. for line in sys.stdin:
  12. left, res = line.rstrip().split(' -> ')
  13. parts = left.split()
  14. if len(parts) == 1:
  15. wires[res] = wrap(parts[0])
  16. elif len(parts) == 2:
  17. op, operand = parts
  18. wires[res] = UNARY, opmap[op], wrap(operand)
  19. elif len(parts) == 3:
  20. left, op, right = parts
  21. wires[res] = BINARY, wrap(left), opmap[op], wrap(right)
  22. def underflow(i):
  23. return ((i + imax) % imax) & (imax - 1)
  24. def compute(wire, cache):
  25. ty = wire[0]
  26. if ty == CONST:
  27. return wire[1]
  28. if ty == WIRE:
  29. x = wire[1]
  30. if x not in cache:
  31. cache[x] = compute(wires[x], cache)
  32. return cache[x]
  33. if ty == UNARY:
  34. op, operand = wire[1:]
  35. return underflow(op(compute(operand, cache)))
  36. assert ty == BINARY
  37. left, op, right = wire[1:]
  38. return underflow(op(compute(left, cache), compute(right, cache)))
  39. a = compute(wires['a'], {})
  40. print(a)
  41. print(compute(wires['a'], {'b': a}))