Logic grid puzzles: how to encode "x is older than y"? #4383
Unanswered
MarcelloTheArcane
asked this question in
General
Replies: 1 comment
-
In another puzzle, there's the constraint "Rachel carried 4 more apples than the girl who used the red basket". I've written the following code for this, but it looks a bit excessive! # Rachel carried four more apples than the girl that used the red basket
# If Rachel collected 24...
name_rachel_amount_24 = model.new_bool_var("name_rachel_amount_24")
model.add_at_least_one(combinations[v] for v in itertools.product(names, amounts, colours) if v[0] == "Rachel" and v[1] == "24").only_enforce_if(name_rachel_amount_24)
model.add(sum(combinations[v] for v in itertools.product(names, amounts, colours) if v[0] == "Rachel" and v[1] == "24") == 0).only_enforce_if(name_rachel_amount_24.Not())
# ...then red collected 20
colour_red_amount_20 = model.new_bool_var("colour_red_amount_20")
model.add_at_least_one(combinations[v] for v in itertools.product(names, amounts, colours) if v[2] == "red" and v[1] == "20").only_enforce_if(colour_red_amount_20)
model.add(sum(combinations[v] for v in itertools.product(names, amounts, colours) if v[2] == "red" and v[1] == "20") == 0).only_enforce_if(colour_red_amount_20.Not())
model.add(colour_red_amount_20 == 1).only_enforce_if(name_rachel_amount_24)
model.add(colour_red_amount_20 == 0).only_enforce_if(name_rachel_amount_24.Not())
name_rachel_amount_24_colour_red_amount_20 = model.new_bool_var("name_rachel_amount_24_colour_red_amount_20")
model.add_bool_and([name_rachel_amount_24, colour_red_amount_20]).only_enforce_if(name_rachel_amount_24_colour_red_amount_20)
model.add(sum([name_rachel_amount_24, colour_red_amount_20]) == 0).only_enforce_if(name_rachel_amount_24_colour_red_amount_20.Not())
# If Rachel collected 26...
name_rachel_amount_26 = model.new_bool_var("name_rachel_amount_26")
model.add_at_least_one(combinations[v] for v in itertools.product(names, amounts, colours) if v[0] == "Rachel" and v[1] == "26").only_enforce_if(name_rachel_amount_26)
model.add(sum(combinations[v] for v in itertools.product(names, amounts, colours) if v[0] == "Rachel" and v[1] == "26") == 0).only_enforce_if(name_rachel_amount_26.Not())
# ...then red collected 22
colour_red_amount_22 = model.new_bool_var("colour_red_amount_22")
model.add_at_least_one(combinations[v] for v in itertools.product(names, amounts, colours) if v[2] == "red" and v[1] == "22").only_enforce_if(colour_red_amount_22)
model.add(sum(combinations[v] for v in itertools.product(names, amounts, colours) if v[2] == "red" and v[1] == "22") == 0).only_enforce_if(colour_red_amount_22.Not())
model.add(colour_red_amount_22 == 1).only_enforce_if(name_rachel_amount_26)
model.add(colour_red_amount_22 == 0).only_enforce_if(name_rachel_amount_26.Not())
name_rachel_amount_26_colour_red_amount_22 = model.new_bool_var("name_rachel_amount_26_colour_red_amount_22")
model.add_bool_and([name_rachel_amount_26, colour_red_amount_22]).only_enforce_if(name_rachel_amount_26_colour_red_amount_22)
model.add(sum([name_rachel_amount_26, colour_red_amount_22]) == 0).only_enforce_if(name_rachel_amount_26_colour_red_amount_22.Not())
# Either (Rachel collected 24 and red collected 20) or (Rachel collected 26 and red collected 22)
model.add_at_least_one([name_rachel_amount_24_colour_red_amount_20, name_rachel_amount_26_colour_red_amount_22]) PS, I'm using |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I'm trying to solve logic grid puzzles using the python SAT solver. For example, this puzzle: https://www.brainzilla.com/logic/logic-grid/kart-racing/
If you're not familiar with these, it's where you have several lists of attributes, and you have to find the correct combination from a given list of clues. My code is inspired by https://wjholden.com/reindeer.html, where each attribute is given a boolean variable.
The thing I'm struggling with is clues like "Alan is one year younger than the pilot who finished third". The code I've come up with is this, but it doesn't feel right since there's a lot of manual variables:
Is there a better way of writing this?
The complete code is here within this dropdown:
Complete code (click to reveal)
Beta Was this translation helpful? Give feedback.
All reactions