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

puzzle = puzzlepedia.parse("""
day in {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}
days = [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
weekdays = [Monday, Tuesday, Wednesday, Thursday, Friday]
# OBSOLETE: "couples" can be gay/lesbian. Sneaky.
#men in   {Samuel,  Simeon,   Steven,    Teller,   Troughton, single}
#women in {Shannon, Siouxsie, Stephanie, Tallulah, Tatiana,   Trixie}
#person in {
#  Samuel,  Simeon,   Steven,    Teller,   Troughton, single,
#  Shannon, Siouxsie, Stephanie, Tallulah, Tatiana,   Trixie,
#}
person in {
  Samuel, Shannon, Simeon, Siouxsie, Stephanie, Steven, Tallulah, Tatiana, Teller, Trixie, Troughton, single
}
table in range(2, 6+1)
model.disable_constraints()

# Constraints.
for p in person:
  sum(p[d] for d in days) == 1
  sum(p[t] for t in table) == 1
for d in days:
  # Two people per table.
  sum(p[d] for p in person) == 2
  # One table per day.
  sum(t[d] for t in table) == 1

def table_n(p):
  return sum(i * p[i] for i in range(2, 6+1))

def day_n(p):
  # FIXME: 
  #return sum(i * p[d] for i, d in enumerate(weekdays))
  return 1*Tuesday[p] + 2*Wednesday[p] + 3*Thursday[p] + 4*Friday[p]

#1 DONE.
starts_s = [Samuel, Simeon,    Steven,   Shannon, Siouxsie, Stephanie]
starts_t = [Teller, Troughton, Tallulah, Tatiana, Trixie]
for d in [Monday, Wednesday, Friday]:
  sum(n[d] for n in starts_s) != sum(n[d] for n in starts_t)
for d in [Tuesday, Thursday]:
  sum(n[d] for n in starts_s) == sum(n[d] for n in starts_t)
for d in [Saturday]:
  any(p[d] for p in person)

#2 DONE.
for d in [Monday, Tuesday, Wednesday, Thursday, Friday]:
  single != d
single == Saturday
Troughton != Saturday
# ...Saturday. He or she sat at the same table as the couple from Monday
all(t[Monday] == t[Saturday] for t in table)

#3 DONE.
for t in table:
  any(p[t] for p in person)

#4 DONE
{Samuel, Tallulah} == {3, 5}
(Samuel == Monday and Tallulah == Friday) or (Samuel == Friday and Tallulah == Monday)

#5 DONE
any(Simeon[a] and Tatiana[b] for a, b in zip(days, days[1:]))

#6 TODO: Steven was at the restaurant sometime before someone ate at table 6
Steven != 6
day_n(Steven) < day_n(6)

#7 DONE
table_n(Teller) < table_n(Simeon)

#8 DONE
#8a Trixie's table number was twice as much as Stephanie's...
# FIXME: Doesn't work: table_n(Trixie) == table_n(Stephanie) * 2
(Stephanie == 3 and Trixie == 6) or (Stephanie == 2 and Trixie == 4)

#8b ... and she was at the restaurant two days after Stephanie.
any(Stephanie[a] and Trixie[b] for a, b in zip(days, days[2:]))

model.grid()
""")


Default constraints disabled

 *	Samuel	Shannon	Simeon	Siouxsie	Stephanie	Steven	Tallulah	Tatiana	Teller	Trixie	Troughton	single		2	3	4	5	6	
Monday	1	0	0	0	0	1	0	0	0	0	0	0		0	1	0	0	0	
Tuesday	0	0	0	0	1	0	0	0	0	0	1	0		1	0	0	0	0	
Wednesday	0	1	0	1	0	0	0	0	0	0	0	0		0	0	0	0	1	
Thursday	0	0	1	0	0	0	0	0	0	1	0	0		0	0	1	0	0	
Friday	0	0	0	0	0	0	1	1	0	0	0	0		0	0	0	1	0	
Saturday	0	0	0	0	0	0	0	0	1	0	0	1		0	1	0	0	0	

2	0	0	0	0	1	0	0	0	0	0	1	0	
3	1	0	0	0	0	1	0	0	1	0	0	1	
4	0	0	1	0	0	0	0	0	0	1	0	0	
5	0	0	0	0	0	0	1	1	0	0	0	0	
6	0	1	0	1	0	0	0	0	0	0	0	0	


In [ ]:
"""
      day |       men |     women | table
   Monday | Troughton |  Tallulah |     5
  Tuesday |    Teller | Stephanie |     4
Wednesday |    Samuel |   Shannon |     6
 Thursday |    Steven |    Trixie |     2
   Friday |    Simeon |  Siouxsie |     3
 Saturday |    single |   Tatiana |     1
 
      day |       men |     women | table
   Monday |    Teller |  Tallulah |     1
  Tuesday | Troughton | Stephanie |     6
Wednesday |    Simeon |   Shannon |     4
 Thursday |    Steven |   Tatiana |     5
   Friday |    Samuel |  Siouxsie |     3
 Saturday |    single |    Trixie |     2
"""

In [ ]: