Earlier quoted context omitted.
I can't edit, but you're right, implications should be bidirectional (expressed in z3 using == instead of z3.Implies) You can limit the number of true answers with "atMost" "atLeast" and "PbEq" I mostly wanted to show off how cool z3 is (especially with python imho), the subtleties of the wording of the problem itself don't seem too important
Could you please post the `fixed` solution in a separate gist? Thanks!
import z3
answers = [z3.Bool(f"answer{i}") for i in range(1,7)]
implications = [
z3.And(answers[1:]), # All of the below
z3.Not(z3.Or(answers[2:])), # None of the below
z3.And(answers[:2]), # All of the above
z3.Or(answers[:3]), # Any of the above
z3.Not(z3.Or(answers[:4])), # None of the above
z3.Not(z3.Or(answers[:5]))] # None of the above
# An answer should be True if and only if its "implication" is true
constraints = [ans == impl for ans, impl in zip(answers, implications)]
z3.solve(constraints) # Prints the right solution
# Try to find another solution by rejecting the previous one
constraints.append(z3.Or(*answers[:4], z3.Not(answers[4]), answers[5]))
z3.solve(constraints) # no solution
https://gist.github.com/Recursing/e09edb6b52f093022d90c66298...