In [40]:
import forge
from puzzle.puzzlepedia import puzzlepedia

puzzle = puzzlepedia.parse("""
import itertools
name in {Beth, Charles, David, Frank, Jessica, Karen, Nolan, Taylor}
(group, place) in ({A, B}, {r1, r2, r3, r4})
# NB: score 3 appears 2x by trial and error. See "Setup"; only one solution.
wins in {0*1, 1*1, 2*1, 3*2, 4*1, 5*1, 6*1}

# Setup:
Ar1.wins > Ar2.wins > Ar3.wins > Ar4.wins
Br1.wins > Br2.wins > Br3.wins > Br4.wins
Ar1.wins + Ar2.wins + Ar3.wins + Ar4.wins == 12
Br1.wins + Br2.wins + Br3.wins + Br4.wins == 12
# NB: The clues are symmetrical, i.e., groups can be swapped.
# Arbitrarily assign a player to produce a unique solution.
any(Beth[g] for g in group.A)

#1:
only_tie = {Charles, Nolan}
Charles == 3
Nolan == 3
#for a, b in itertools.combinations(name, 2):
#  all((a[w] == b[w]) == ({a, b} == only_tie) for w in wins)

#2a: Frank and Taylor were in different groups...
any(Frank[g] for g in group.A) != any(Taylor[g] for g in group.A)
#2b: ...and were placed 1st / 2nd.
((any(Frank[g] for g in place.r1) and any(Taylor[g] for g in place.r2)) or
    (any(Taylor[g] for g in place.r1) and any(Frank[g] for g in place.r2)))

#3:
Jessica.wins == David.wins + Taylor.wins

#4a: Karen was in the same group as Nolan.
any(Karen[g] for g in group.A) == any(Nolan[g] for g in group.A)

#4b: Karen's score > Beth's score.
Karen.wins > Beth.wins

#5: "The player who had won fewer games (...) was victorious".
# Group A advances?
if Ar1.wins < Br2.wins:
  semi_1_winner = Ar1.wins
else:
  semi_1_winner = Br2.wins
if Ar2.wins < Br1.wins:
  semi_2_winner = Ar2.wins
else:
  semi_2_winner = Br1.wins

if semi_1_winner < semi_2_winner:
  winner = semi_1_winner
else:
  winner = semi_2_winner

print('winner:', winner)
""")


winner: 3 == (((((((((group_place["Ar1"].wins[1] + 2*group_place["Ar1"].wins[2] + 3*group_place["Ar1"].wins[3] + 4*group_place["Ar1"].wins[4] + 5*group_place["Ar1"].wins[5] + 6*group_place["Ar1"].wins[6]) < (group_place["Br2"].wins[1] + 2*group_place["Br2"].wins[2] + 3*group_place["Br2"].wins[3] + 4*group_place["Br2"].wins[4] + 5*group_place["Br2"].wins[5] + 6*group_place["Br2"].wins[6])) == True) * (group_place["Ar1"].wins[1] + 2*group_place["Ar1"].wins[2] + 3*group_place["Ar1"].wins[3] + 4*group_place["Ar1"].wins[4] + 5*group_place["Ar1"].wins[5] + 6*group_place["Ar1"].wins[6])) + ((((group_place["Ar1"].wins[1] + 2*group_place["Ar1"].wins[2] + 3*group_place["Ar1"].wins[3] + 4*group_place["Ar1"].wins[4] + 5*group_place["Ar1"].wins[5] + 6*group_place["Ar1"].wins[6]) < (group_place["Br2"].wins[1] + 2*group_place["Br2"].wins[2] + 3*group_place["Br2"].wins[3] + 4*group_place["Br2"].wins[4] + 5*group_place["Br2"].wins[5] + 6*group_place["Br2"].wins[6])) == False) * (group_place["Br2"].wins[1] + 2*group_place["Br2"].wins[2] + 3*group_place["Br2"].wins[3] + 4*group_place["Br2"].wins[4] + 5*group_place["Br2"].wins[5] + 6*group_place["Br2"].wins[6]))) < (((((group_place["Ar2"].wins[1] + 2*group_place["Ar2"].wins[2] + 3*group_place["Ar2"].wins[3] + 4*group_place["Ar2"].wins[4] + 5*group_place["Ar2"].wins[5] + 6*group_place["Ar2"].wins[6]) < (group_place["Br1"].wins[1] + 2*group_place["Br1"].wins[2] + 3*group_place["Br1"].wins[3] + 4*group_place["Br1"].wins[4] + 5*group_place["Br1"].wins[5] + 6*group_place["Br1"].wins[6])) == True) * (group_place["Ar2"].wins[1] + 2*group_place["Ar2"].wins[2] + 3*group_place["Ar2"].wins[3] + 4*group_place["Ar2"].wins[4] + 5*group_place["Ar2"].wins[5] + 6*group_place["Ar2"].wins[6])) + ((((group_place["Ar2"].wins[1] + 2*group_place["Ar2"].wins[2] + 3*group_place["Ar2"].wins[3] + 4*group_place["Ar2"].wins[4] + 5*group_place["Ar2"].wins[5] + 6*group_place["Ar2"].wins[6]) < (group_place["Br1"].wins[1] + 2*group_place["Br1"].wins[2] + 3*group_place["Br1"].wins[3] + 4*group_place["Br1"].wins[4] + 5*group_place["Br1"].wins[5] + 6*group_place["Br1"].wins[6])) == False) * (group_place["Br1"].wins[1] + 2*group_place["Br1"].wins[2] + 3*group_place["Br1"].wins[3] + 4*group_place["Br1"].wins[4] + 5*group_place["Br1"].wins[5] + 6*group_place["Br1"].wins[6])))) == True) * (((((group_place["Ar1"].wins[1] + 2*group_place["Ar1"].wins[2] + 3*group_place["Ar1"].wins[3] + 4*group_place["Ar1"].wins[4] + 5*group_place["Ar1"].wins[5] + 6*group_place["Ar1"].wins[6]) < (group_place["Br2"].wins[1] + 2*group_place["Br2"].wins[2] + 3*group_place["Br2"].wins[3] + 4*group_place["Br2"].wins[4] + 5*group_place["Br2"].wins[5] + 6*group_place["Br2"].wins[6])) == True) * (group_place["Ar1"].wins[1] + 2*group_place["Ar1"].wins[2] + 3*group_place["Ar1"].wins[3] + 4*group_place["Ar1"].wins[4] + 5*group_place["Ar1"].wins[5] + 6*group_place["Ar1"].wins[6])) + ((((group_place["Ar1"].wins[1] + 2*group_place["Ar1"].wins[2] + 3*group_place["Ar1"].wins[3] + 4*group_place["Ar1"].wins[4] + 5*group_place["Ar1"].wins[5] + 6*group_place["Ar1"].wins[6]) < (group_place["Br2"].wins[1] + 2*group_place["Br2"].wins[2] + 3*group_place["Br2"].wins[3] + 4*group_place["Br2"].wins[4] + 5*group_place["Br2"].wins[5] + 6*group_place["Br2"].wins[6])) == False) * (group_place["Br2"].wins[1] + 2*group_place["Br2"].wins[2] + 3*group_place["Br2"].wins[3] + 4*group_place["Br2"].wins[4] + 5*group_place["Br2"].wins[5] + 6*group_place["Br2"].wins[6])))) + ((((((((group_place["Ar1"].wins[1] + 2*group_place["Ar1"].wins[2] + 3*group_place["Ar1"].wins[3] + 4*group_place["Ar1"].wins[4] + 5*group_place["Ar1"].wins[5] + 6*group_place["Ar1"].wins[6]) < (group_place["Br2"].wins[1] + 2*group_place["Br2"].wins[2] + 3*group_place["Br2"].wins[3] + 4*group_place["Br2"].wins[4] + 5*group_place["Br2"].wins[5] + 6*group_place["Br2"].wins[6])) == True) * (group_place["Ar1"].wins[1] + 2*group_place["Ar1"].wins[2] + 3*group_place["Ar1"].wins[3] + 4*group_place["Ar1"].wins[4] + 5*group_place["Ar1"].wins[5] + 6*group_place["Ar1"].wins[6])) + ((((group_place["Ar1"].wins[1] + 2*group_place["Ar1"].wins[2] + 3*group_place["Ar1"].wins[3] + 4*group_place["Ar1"].wins[4] + 5*group_place["Ar1"].wins[5] + 6*group_place["Ar1"].wins[6]) < (group_place["Br2"].wins[1] + 2*group_place["Br2"].wins[2] + 3*group_place["Br2"].wins[3] + 4*group_place["Br2"].wins[4] + 5*group_place["Br2"].wins[5] + 6*group_place["Br2"].wins[6])) == False) * (group_place["Br2"].wins[1] + 2*group_place["Br2"].wins[2] + 3*group_place["Br2"].wins[3] + 4*group_place["Br2"].wins[4] + 5*group_place["Br2"].wins[5] + 6*group_place["Br2"].wins[6]))) < (((((group_place["Ar2"].wins[1] + 2*group_place["Ar2"].wins[2] + 3*group_place["Ar2"].wins[3] + 4*group_place["Ar2"].wins[4] + 5*group_place["Ar2"].wins[5] + 6*group_place["Ar2"].wins[6]) < (group_place["Br1"].wins[1] + 2*group_place["Br1"].wins[2] + 3*group_place["Br1"].wins[3] + 4*group_place["Br1"].wins[4] + 5*group_place["Br1"].wins[5] + 6*group_place["Br1"].wins[6])) == True) * (group_place["Ar2"].wins[1] + 2*group_place["Ar2"].wins[2] + 3*group_place["Ar2"].wins[3] + 4*group_place["Ar2"].wins[4] + 5*group_place["Ar2"].wins[5] + 6*group_place["Ar2"].wins[6])) + ((((group_place["Ar2"].wins[1] + 2*group_place["Ar2"].wins[2] + 3*group_place["Ar2"].wins[3] + 4*group_place["Ar2"].wins[4] + 5*group_place["Ar2"].wins[5] + 6*group_place["Ar2"].wins[6]) < (group_place["Br1"].wins[1] + 2*group_place["Br1"].wins[2] + 3*group_place["Br1"].wins[3] + 4*group_place["Br1"].wins[4] + 5*group_place["Br1"].wins[5] + 6*group_place["Br1"].wins[6])) == False) * (group_place["Br1"].wins[1] + 2*group_place["Br1"].wins[2] + 3*group_place["Br1"].wins[3] + 4*group_place["Br1"].wins[4] + 5*group_place["Br1"].wins[5] + 6*group_place["Br1"].wins[6])))) == False) * (((((group_place["Ar2"].wins[1] + 2*group_place["Ar2"].wins[2] + 3*group_place["Ar2"].wins[3] + 4*group_place["Ar2"].wins[4] + 5*group_place["Ar2"].wins[5] + 6*group_place["Ar2"].wins[6]) < (group_place["Br1"].wins[1] + 2*group_place["Br1"].wins[2] + 3*group_place["Br1"].wins[3] + 4*group_place["Br1"].wins[4] + 5*group_place["Br1"].wins[5] + 6*group_place["Br1"].wins[6])) == True) * (group_place["Ar2"].wins[1] + 2*group_place["Ar2"].wins[2] + 3*group_place["Ar2"].wins[3] + 4*group_place["Ar2"].wins[4] + 5*group_place["Ar2"].wins[5] + 6*group_place["Ar2"].wins[6])) + ((((group_place["Ar2"].wins[1] + 2*group_place["Ar2"].wins[2] + 3*group_place["Ar2"].wins[3] + 4*group_place["Ar2"].wins[4] + 5*group_place["Ar2"].wins[5] + 6*group_place["Ar2"].wins[6]) < (group_place["Br1"].wins[1] + 2*group_place["Br1"].wins[2] + 3*group_place["Br1"].wins[3] + 4*group_place["Br1"].wins[4] + 5*group_place["Br1"].wins[5] + 6*group_place["Br1"].wins[6])) == False) * (group_place["Br1"].wins[1] + 2*group_place["Br1"].wins[2] + 3*group_place["Br1"].wins[3] + 4*group_place["Br1"].wins[4] + 5*group_place["Br1"].wins[5] + 6*group_place["Br1"].wins[6])))))

In [ ]: