from itertools import product funcs = [ lambda x1, x2, x3, x4: not x2, lambda x1, x2, x3, x4: x1, lambda x1, x2, x3, x4: x1 ^ x4, lambda x1, x2, x3, x4: x3, ] sequential_sync_funcs = [ lambda x1, x2, x3, x4: not x2, lambda x1, x2, x3, x4: not x2, lambda x1, x2, x3, x4: (not x2) ^ x4, lambda x1, x2, x3, x4: (not x2) ^ x4, ] nodes = [] def init(initial_state): global nodes nodes = [bool(i) for i in initial_state] assert len(funcs) == len(nodes) def synchronous_update(): global nodes, funcs temp = nodes.copy() for i in range(len(funcs)): temp[i] = funcs[i](*nodes) nodes = temp def sequential_update(order): global nodes, funcs assert len(order) == len(nodes) for i in order: nodes[i] = funcs[i](*nodes) def state_to_str(): return "".join(str(int(i)) for i in nodes) def simulate(initial_state): print("press ENTER to simulate one step. press 'q' before ENTER to exit") init(initial_state) state = state_to_str() while input() != "q": update() print(state + " -> " + state_to_str(), end="") def get_table(): for i in product((0, 1), repeat=4): init(tuple(i)) state = state_to_str() update() print(state + " -> " + state_to_str()) def update(): return synchronous_update() return sequential_update([0, 1, 2, 3]) # return block_sequential_update(...) # return asynchronous_deterministic_update(...) def main(): get_table() if __name__ == "__main__": main()