kostis-init/CP-Bench huggingface dataset:
Problem description:
If you start with my age, in years, and apply the four operations:  [    +2  /8     -3  *7  ]  in some order, then the final answer you get is my husband's age.  Funnily enough, if you start with his age and apply the same four operations in a different order, then you get my age.  What are our two ages?  Print my age and my husband's age (m, h).

Input data:

Decision variables: m, h

CPMpy model:
# Import libraries
from cpmpy import *
import json

def check(perm, old, new):
    return [
        (perm == 0).implies(new == old + 2),
        # (perm == 1).implies(new == old / 8), # This give a lot of bad solutions
        (perm == 1).implies(8*new == old),     # This works
        (perm == 2).implies(new == old - 3),
        (perm == 3).implies(new == old * 7)
        ]

n = 4

perms = ["+2", "/8", "-3", "*7"]

# ages 16..120
age_low = 16
age_high = 120

# variables
m = intvar(age_low, age_high, name="m")  # my age
h = intvar(age_low, age_high, name="h")  # my age

perm1 = intvar(0, n - 1, shape=n, name="perm1")
perm2 = intvar(0, n - 1, shape=n, name="perm2")

# for calculating my age and husband's age
mlist = intvar(1, 1000, shape=n + 1, name="mlist")
hlist = intvar(1, 1000, shape=n + 1, name="hlist")

# constraints
model = Model([AllDifferent(perm1),
               AllDifferent(perm2),

               # same operations in different order
               sum([perm1[i] != perm2[i] for i in range(n)]) > 0,

               # find husbands age, start with my age
               hlist[0] == m,

               # husband's age is last in hlist
               h == hlist[n],

               # checking my age, start with husband's age
               mlist[0] == h,

               # my age is last in mlist
               m == mlist[n],

               # check the operations
               [check(perm1[i], hlist[i], hlist[i + 1]) for i in range(n)],
               [check(perm2[i], mlist[i], mlist[i + 1]) for i in range(n)],

               # Symmetry breaking: I'm younger than husband
               # m < h
               ])

# Solve
model.solve()

# Print the solution
solution = {
    "m": m.value(),
    "h": h.value()
}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Four friends (two women named Debra and Janet, and two men named Hugh and Rick) found that each of them is allergic to something different: eggs, mold, nuts and ragweed. We would like to match each one's surname (Baxter, Lemon, Malone and Fleet) with his or her allergy. We know that:  - Rick is not allergic to mold  - Baxter is allergic to eggs  - Hugh is neither surnamed Lemon nor Fleet  - Debra is allergic to ragweed  - Janet (who isn't Lemon) is neither allergic to eggs nor to mold  Print the values of each food (eggs, mold, nuts, ragweed) and surname (baxter, lemon, malone, fleet) for each friend, where Debra = 0, Janet = 1, Hugh = 2, Rick = 3.

Input data:

Decision variables: malone, baxter, nuts, ragweed, mold, fleet, lemon, eggs

CPMpy model:
# Import libraries
from cpmpy import *
import json

n = 4
friends = Debra, Janet, Hugh, Rick = list(range(n))
friends_s = ["Debra", "Janet", "Hugh", "Rick"]

# foods[i] is the friend allergic to the ith food
eggs, mold, nuts, ragweed = foods = intvar(0, n - 1, shape=n, name="foods")
foods_s = ["eggs", "mold", "nuts", "ragweed"]

# surnames[i] is the friend with the ith surname
baxter, lemon, malone, fleet = surnames = intvar(0, n - 1, shape=n, name="surnames")
surnames_s = ["baxter", "lemon", "malone", "fleet"]

model = Model([AllDifferent(foods),
               AllDifferent(surnames),

               mold != Rick,
               eggs == baxter,
               lemon != Hugh,
               fleet != Hugh,
               ragweed == Debra,
               lemon != Janet,
               eggs != Janet,
               mold != Janet])

# Solve
model.solve()

# Print the solution
solution = {"eggs": eggs.value(), "mold": mold.value(), "nuts": nuts.value(), "ragweed": ragweed.value(),
            "baxter": baxter.value(), "lemon": lemon.value(), "malone": malone.value(), "fleet": fleet.value()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Requires exactly m variables in x to take one of the values in v.  Print the array x (x).

Input data:
n = 5  # Length of x m = 3  # Number of values v = [1, 5, 8]  # Values to be among in x

Decision variables: x

CPMpy model:
# Data
n = 5  # Length of x
m = 3  # Number of values
v = [1, 5, 8]  # Values to be among in x
# End of data

# Import libraries
from cpmpy import *
import json


def among(m,x,v):
  """
  among(m,x,v)

  Requires exactly m variables in x to take one of the values in v.
  """
  return [m == sum([x[i] == j for i in range(len(x)) for j in v])]


# Decision variables
x = intvar(1, 8, shape=n, name="x")

# Model
model = Model([
    among(m, x, v)
])

# Solve the model
model.solve()

# Print the solution
solution = {"x": x.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Schedule 4 people into 4 interview slots based on their free-busy schedules.  Print the assignment of people to slots (x) where 1 means the person is assigned to the slot and 0 means the person is not assigned to the slot.

Input data:
m = [     [1, 1, 1, 1],     [0, 1, 1, 0],     [1, 0, 0, 1],     [1, 0, 0, 1] ]  # Matrix representing the free-busy schedules

Decision variables: x

CPMpy model:
# Data
m = [
    [1, 1, 1, 1],
    [0, 1, 1, 0],
    [1, 0, 0, 1],
    [1, 0, 0, 1]
]  # Matrix representing the free-busy schedules
# End of data

# Import libraries
from cpmpy import *
import json
import random

model = Model()

n = len(m)

# decision variables

# the assignment of persons to a slot (appointment number 0..n)
x = boolvar(shape=(n, n), name="x")

# constraints

for i in range(n):
    # ensure a free slot
    model += (sum([m[i][j] * x[(i, j)] for j in range(n)]) == 1)

    # ensure one assignment per slot
    model += (sum([x[(i, j)] for j in range(n)]) == 1)
    model += (sum([x[(j, i)] for j in range(n)]) == 1)
# Solve the model
model.solve()

# Print the solution
solution = {"x": x.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
How close can the young archer come to scoring a total of 100 using as many arrows as she pleases? The targets are: 16, 17, 23, 24, 39, 40.  Print the number of hits on each target (hits).

Input data:

Decision variables: hits

CPMpy model:
# Import libraries
from cpmpy import *
import json

# Parameters
targets = [16, 17, 23, 24, 39, 40]
n = len(targets)
target_score = 100

# Decision variables
hits = intvar(0, 100, shape=n, name="hits")
score = intvar(0, 100, name="score")
deviation = intvar(0, 100, name="deviation")

# Model
model = Model([
    score == sum(hits * targets),
    deviation == abs(target_score - score)
])

# Objective
model.minimize(deviation)

# Solve the model
model.solve()

# Print the solution
solution = {"hits": hits.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Harriet, upon returning from the mall, is happily describing her four shoe purchases to her friend Aurora. Aurora just loves the four different kinds of shoes that Harriet bought   (ecru espadrilles, fuchsia flats, purple pumps, and suede sandals), but Harriet can't recall at which different store   (Foot Farm, Heels in a Handcart, The Shoe Palace, or Tootsies) she got each pair. Can you help these two figure out the order in which Harriet bought each pair of shoes, and where she bought each?  1. Harriet bought fuchsia flats at Heels in a Handcart. 2. The store she visited just after buying her purple pumps was not   Tootsies. 3. The Foot Farm was Harriet's second stop. 4. Two stops after leaving The Shoe Place, Harriet bought her suede   sandals.  Print the values of each shoe (ecruespadrilles, fuchsiaflats, purplepumps, suedesandals) and store (footfarm, heelsinahandcart, theshoepalace, tootsies), such that the same value denotes the same shoe or store.

Input data:

Decision variables: ecruespadrilles, purplepumps, theshoepalace, suedesandals, footfarm, fuchsiaflats, tootsies, heelsinahandcart

CPMpy model:
# Import libraries
from cpmpy import *
import numpy as np
import json


n = 4
model = Model()

shoes = intvar(1, n, shape=n, name="shoes")
ecruespadrilles, fuchsiaflats, purplepumps, suedesandals = shoes

store = intvar(1, n, shape=n, name="store")
footfarm, heelsinahandcart, theshoepalace, tootsies = store

model += [AllDifferent(shoes),
          AllDifferent(store),

          # 1. Harriet bought fuchsia flats at Heels in a Handcart.
          fuchsiaflats == heelsinahandcart,

          # 2. The store she visited just after buying her purple pumps was not
          #    Tootsies.
          purplepumps + 1 != tootsies,

          # 3. The Foot Farm was Harriet's second stop.
          footfarm == 2,

          # 4. Two stops after leaving The Shoe Place, Harriet bought her suede
          # sandals.
          theshoepalace + 2 == suedesandals
          ]

model.solve()

# Print
solution = {"ecruespadrilles": ecruespadrilles.value(),
            "fuchsiaflats": fuchsiaflats.value(),
            "purplepumps": purplepumps.value(),
            "suedesandals": suedesandals.value(),
            "footfarm": footfarm.value(),
            "heelsinahandcart": heelsinahandcart.value(),
            "theshoepalace": theshoepalace.value(),
            "tootsies": tootsies.value()
            }
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Assign people to 4 tasks with different costs, so that the total cost is minimized. Each task must be assigned to exactly one person, but it is not necessary to assign all people to a task.  Print whether each task is assigned to a person (x), where 1 means the task is assigned to the person and 0 means the task is not assigned to the person.

Input data:
cost = [  # Cost matrix, rows are tasks, columns are people     [14, 5, 8, 7, 15],     [2, 12, 6, 5, 3],     [7, 8, 3, 9, 7],     [2, 4, 6, 10, 1] ]  # Cost matrix

Decision variables: x

CPMpy model:
# Data
cost = [  # Cost matrix, rows are tasks, columns are people
    [14, 5, 8, 7, 15],
    [2, 12, 6, 5, 3],
    [7, 8, 3, 9, 7],
    [2, 4, 6, 10, 1]
]  # Cost matrix
# End of data

# Import libraries
from cpmpy import *
import numpy as np
import json

# Parameters
rows = len(cost)
cols = len(cost[0])

# Decision variables
max_cost = np.sum(np.array(cost))

total_cost = intvar(0, max_cost, name='cost')
x = boolvar(shape=(rows, cols), name="x")

model = Model(
    total_cost >= 0,
    total_cost == np.sum([x_row * cost_row for (x_row, cost_row) in zip(x, cost)]),

    # exacly one assignment per row, all rows (tasks) must be assigned.
    [sum(row) == 1 for row in x],

    # zero or one assignments per column (people)
    [sum(col) <= 1 for col in x.transpose()],
)

# Objective
model.minimize(total_cost)

# Solve the model
model.solve()

# Print the solution
solution = {"x": x.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Given an integer n > 0 and an integer m >= 0, find a non-empty finite series S=(s0, s1, ..., sn, sn+1) such that ( 1) there are si occurrences of i in S for each integer i ranging from 0 to n, and (2) sn+1=m.  Print the series S (s).

Input data:
n = 27 m = 5

Decision variables: s

CPMpy model:
# Data
n = 27
m = 5
# End of data

# Import libraries
from cpmpy import *
import json


def count(a, val, c):
    """
    count(a,val,c)

    c is the number of occurrences of val in array a.
    """
    return [c == sum([a[i] == val for i in range(len(a))])]


def global_cardinality_count(a, gcc):
    """
    global_cardinality_count(a, gcc)

    Global cardinality count: Collect the number of occurrences of each value 0..a.ub
    in gcc. The array gcc must be of length 0..ub.
    """
    n = len(a)
    ub = max([a[i].ub for i in range(n)])
    constraints = []
    for i in range(ub + 1):
        constraints += [count(a, i, gcc[i])]

    return constraints


def autoref(s):
    """
    autoref(s)
    Ensure that the number of occurrences of i in s is s[i].
    s should be an array of 0..n+1
    """
    return [global_cardinality_count(s, s)]


# Decision Variables
s = intvar(0, n, shape=n + 2, name="s")

# Model
model = Model(s[n + 1] == m, autoref(s))

# Solve the model
model.solve()

# Print the solution
solution = {"s": s.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
You have five bales of hay.  For some reason, instead of being weighed individually, they were weighed in all possible combinations of two. The weights of each of these combinations were written down and arranged in numerical order, without keeping track of which weight matched which pair of bales. The weights, in kilograms, were 80, 82, 83, 84, 85, 86, 87, 88, 90, and 91.  Print the weights of each bale (bales).

Input data:

Decision variables: bales

CPMpy model:
# Import libraries
from cpmpy import *
import json

# Parameters
n = 5
weights = [80, 82, 83, 84, 85, 86, 87, 88, 90, 91]

# variables
bales = intvar(0, 50, shape=n, name="bales")

model = Model()


def increasing(args):
    """
    Ensure that the values in args are increasing.
    """
    return [args[i - 1] <= args[i] for i in range(1, len(args))]


# constraints
model += [increasing(bales)]

for w in weights:
    i = intvar(0, n - 1)
    j = intvar(0, n - 1)
    model += [i < j]
    model += [w == bales[i] + bales[j]]

# Solve the model
model.solve()

# Print the solution
solution = {"bales": bales.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
In three dollars, you get 5 bananas, in five dollars, 7 oranges, in seven dollars, 9 mangoes and in nine dollars, three apples, I need to purchase 100 fruits in 100 dollars. Please keep in mind that all type of fruits need to be purchased but I do not like banana and apple, so these should be of minimum quantity.  Print the quantities of each fruit (bananas, oranges, mangoes, apples).

Input data:

Decision variables: oranges, bananas, apples, mangoes

CPMpy model:
# Import libraries
from cpmpy import *
import json

x = intvar(1, 100, shape=4, name="x")
bananas, oranges, mangoes, apples = x

the_sum = intvar(1, 2000, name="the_sum")

model = Model([the_sum == bananas + apples,
               # This don't work since "/" does integer division
               # 3*bananas/5 + 5*oranges/7 + 7*mangoes/9 + 9*apples/3 == 100,
               # we multiply with 3*5*7*9=945 on both sides to weed out the divisions
               3 * bananas * 189 + 5 * oranges * 135 + 7 * mangoes * 105 + 9 * apples * 315 == 100 * 945,
               sum(x) == 100
               ])

model.minimize(the_sum)

# Solve the model
model.solve()

# Print the solution
solution = {
    "bananas": bananas.value(),
    "oranges": oranges.value(),
    "mangoes": mangoes.value(),
    "apples": apples.value()
}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Hosting a dinner party requires several skills to pull off a successful evening. One of your duties, aside from preparing dinner and selecting the drinks, is to make sure your guests enjoy themselves.  Figure 1 shows a dinner table with six seats for your guests. Some guests, however, do not get along with each other. If two guests who do not get along are seated next to each other, it will create conflict at dinner. As host, you must arrange the guests in a seating order that minimizes conflict.  Andrew will only sit next to Dave and Frank; Betty will only sit next to Cara and Erica; Cara will only sit next to Betty and Frank; Dave will only sit next to Andrew and Erica; Erica will only sit next to Betty and Dave; Frank will only sit next to Andrew and Cara.  [   Figure 1 shows the following arrangement:                Andrew        Frank         Betty        Erica         Cara               Dave  ]  In the example seating arrangement above, there are three conflicts (Andrew and Betty, Cara and Dave, Erica and Frank).  Question:  What seating arrangement will minimize the conflict at dinner?  Print the list of guests (x) in the seating order, where 0 is Andrew, and the rest are in alphabetical order.

Input data:

Decision variables: x

CPMpy model:
# Import libraries
from cpmpy import *
import json


def member_of(x, val):
    """
    member_of(x, val)

    Ensures that the value `val` is in the array `x`.
    """
    n = len(x)
    # cc = intvar(0,n)
    # constraints = [count(x, val, cc), cc >  0]
    constraints = [sum([x[i] == val for i in range(n)]) > 0]
    return constraints


model = Model()

n = 6

Andrew = 0
Betty = 1
Cara = 2
Dave = 3
Erica = 4
Frank = 5

prefs = cpm_array([
    [Dave, Frank],  # Andrew
    [Cara, Erica],  # Betty
    [Betty, Frank],  # Cara
    [Andrew, Erica],  # Dave
    [Betty, Dave],  # Erica
    [Andrew, Cara]  # Frank
])

# declare variables
x = intvar(0, n - 1, shape=n, name="x")

#
# constraints
#
model += (AllDifferent(x))

# symmetry breaking
model += (x[0] == Andrew)

for i in range(n):
    # This don't work:
    # TypeError: object of type 'Element' has no len()
    # model += [member_of(prefs[x[i]], x[(i-1) % n])]
    # model += [member_of(prefs[x[i]], x[(i+1) % n])]

    # It works if we expand the array:
    model += [member_of([prefs[x[i], j] for j in range(2)], x[(i - 1) % n])]
    model += [member_of([prefs[x[i], j] for j in range(2)], x[(i + 1) % n])]

    # Another approach that works
    # model += [sum([prefs[x[i],j] == x[(i-1) % n] for j in range(2)])>0]
    # model += [sum([prefs[x[i],j] == x[(i+1) % n] for j in range(2)])>0]

# Solve the model
model.solve()

# Print the solution
solution = {"x": x.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Nontransitive dice a la The Big Bang Theory in Comet Thore Graepel (thoregraepel@googlemail.com)  The idea is to create a set of five dice such that the dominance relationships between the dice is isomorphic to the corresponding relationships in the game Rock-Paper-Scissors extended by the choices Lizard and Spock. (originally from http://www.samkass.com/theories/RPSSL.html).  Each choice beats two other choices and is beaten by two other choices. In particular, we have the following ten 'beats' relationships  1:  Rock(1) crushes Scissors(3) 2:  Rock(1) crushes Lizard(4) 3:  Paper(2) covers Rock(1) 4:  Paper(2) disproves Spock(5) 5:  Scissors(3) cuts Paper(2) 6:  Scissors(3) decapitate Lizard(4) 7:  Lizard(4) eats Paper(2) 8:  Lizard(4) poisons Spock(5) 9:  Spock(5) vaporizes Rock(1) 10: Spock(5) smashes Scissors(3)  Print the dice (dice) as a list of lists where each sublist is a die.

Input data:

Decision variables: dice

CPMpy model:
# Import libraries
from cpmpy import *
import json


def increasing(args):
    """
    Ensure that the values in args are increasing.
    """
    return [args[i - 1] <= args[i] for i in range(1, len(args))]


rock = 0
paper = 1
scissors = 2
lizard = 3
spock = 4

m = 5  # number of dice
n = 8  # number of faces of each die
f = 2 * n  # max face value of dice
k = 10  # number of competitions
edge = [
    [rock, scissors],
    [rock, lizard],
    [paper, rock],
    [paper, spock],
    [scissors, paper],
    [scissors, lizard],
    [lizard, paper],
    [lizard, spock],
    [spock, rock],
    [spock, scissors]
]

#
# declare variables
#

dice = intvar(1, f, shape=(m, n), name="dice")
comp = intvar(0, n * n, shape=(k, 2), name="comp")
max_val = intvar(0, f, name="max_val")

model = Model()
#
# constraints
#
model += (max_val == max(dice))

# Symmetry breaking
# order of the number of each die, lowest first
model += [increasing(dice[i]) for i in range(m)]
# This is faster but yield max_val = 11 instead of the correct 9!
# model += [lex_less(dice[i],dice[i+1]) for i in range(m-1)]
model += [dice[0, 0] == 1]
model += [AllDifferent([dice[i, 0] for i in range(m)])]

# and now we roll...
for c in range(k):
    model += (comp[c, 0] == sum([dice[edge[c][0], r1] > dice[edge[c][1], r2]
                                 for r1 in range(n) for r2 in range(n)]))

    model += (comp[c, 1] == sum([dice[edge[c][1], r1] > dice[edge[c][0], r2]
                                 for r1 in range(n) for r2 in range(n)]))

    model += (comp[c, 0] > comp[c, 1])

    # added later by Thore:
    model += (comp[c, 0] + comp[c, 1] == n * n)  # make sure there are no ties

# Solve the model
model.solve()

# Print the solution
solution = {"dice": dice.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Given several items of specific weights and a number of bins of a fixed capacity, assign each item to a bin so that the total weight of the items in each bin does not exceed the capacity.  Print the bin each item is assigned to (bins) as a list of numbers.

Input data:
weights = [4, 3, 1, 3, 2, 5, 2] capacity = 5 num_bins = 5

Decision variables: bins

CPMpy model:
# Data
weights = [4, 3, 1, 3, 2, 5, 2]
capacity = 5
num_bins = 5
# End of data

# Import libraries
from cpmpy import *
import json

# Parameters
n = len(weights)

# Decision variables
bins = intvar(0, num_bins - 1, shape=n, name="bins")  # Which bin each item is assigned to

# Model
model = Model([
    [sum(weights[j] * (bins[j] == i) for j in range(n)) <= capacity for i in range(n)]
])

# Solve the model
model.solve()

# Print the solution
solution = {"bins": bins.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Tommy was given 15 coins for his birthday (half-crowns, shillings and sixpence). When he added it up, he found that he had £1. 5s. 6d (one pound 5 shillings and 6 pences, see below). How many half-crowns was he given?  (This puzzle involve coins from the old British currency. A pound is 20 shillings and a shilling is 12 pence (hence, a pound is 20 ⋅ 12 = 240 pence). A half-sovereign is 10 shillings, a crown is 5 shillings, a double-florin is four shillings, a half-crown is 2 shillings and sixpence (hence, a half-crown is 2 ⋅ 12 + 6 = 30 pence), a florin is 2 shillings. £3. 2s. 6d. means three pounds, two shillings and six pence.).  Print the number of half-crowns he was given (half_crowns).

Input data:

Decision variables: half_crowns

CPMpy model:
# Import libraries
from cpmpy import *
import json

# Parameters
coin_types = 3
values = [30, 12, 6]  # Values in pence for half-crowns, shillings, and sixpences
total_value = 240 + 5 * 12 + 6  # Total value in pence
total_coins = 15  # Total number of coins

# Decision variables
coins = intvar(1, 15, shape=coin_types, name="coins")
half_crowns = coins[0]

# Model
model = Model([
    sum(values[i] * coins[i] for i in range(coin_types)) == total_value,
    sum(coins) == total_coins
])

# Solve the model
model.solve()

# Print the solution
solution = {
    "half_crowns": half_crowns.value(),
}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
You have 40 bowls, all placed in a line at exact intervals of 1 meter. You also have 9 oranges. You wish to place all the oranges in the bowls, no more than one orange in each bowl, so that there are no three oranges A, B, and C such that the distance between A and B is equal to the distance between B and C.  Print a solution to the problem as a list of 9 numbers between 1 and 40 representing the bowls in which the oranges are placed (x).

Input data:

Decision variables: x

CPMpy model:
# Import libraries
from cpmpy import *
import json

# Parameters
n = 40  # Number of bowls
m = 9  # Number of oranges

# Decision variables
x = intvar(1, n, shape=m, name="x")


def increasing(args):
    """
    Ensure that the values in args are increasing.
    """
    return [args[i - 1] <= args[i] for i in range(1, len(args))]


# Model
model = Model([
    AllDifferent(x),
    increasing(x)
])

# Constraint to ensure no three oranges A, B, and C have equal distances
for i in range(m):
    for j in range(m):
        for k in range(m):
            if i < j < k:
                model += ((x[j] - x[i]) != (x[k] - x[j]))

# Solve the model
model.solve()

# Print the solution
solution = {"x": x.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script