kostis-init/CP-Bench huggingface dataset:
Problem description:
We want to assign a different colour to the following countries: Belgium, Denmark, France, Germany, Netherlands and Luxembourg. Two neighbouring countries cannot have the same colour. You can use integers starting from 1 to represent the colours. Find a colouring that minimizes the number of colours used.  Print the colours assigned to each country as a list (colors).

Input data:
graph = [  # the adjacency of the countries, (i, j) means that country i is adjacent to country j     [3, 1],     [3, 6],     [3, 4],     [6, 4],     [6, 1],     [1, 5],     [1, 4],     [4, 5],     [4, 2] ]

Decision variables: colors

CPMpy model:
# Data
graph = [  # the adjacency of the countries, (i, j) means that country i is adjacent to country j
    [3, 1],
    [3, 6],
    [3, 4],
    [6, 4],
    [6, 1],
    [1, 5],
    [1, 4],
    [4, 5],
    [4, 2]
]
# End of data

# Import libraries
from cpmpy import *
import json

num_edges = 9
num_nodes = 6

# Decision Variables
colors = intvar(1, num_nodes, shape=num_nodes)  # the colour assigned to each country

# Constraints
model = Model()

# Two neighbouring countries cannot have the same colour
for i, j in graph:
    # Python uses 0-based indexing, but the countries are 1-based, so we need to subtract 1 from the indices
    model += colors[i - 1] != colors[j - 1]

# Objective
# Find a colouring that minimizes the number of colours used
model.minimize(max(colors))

# Solve
model.solve()

# Print the solution
solution = {"colors": colors.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
A farmer has 25 cows numbered 1 to 25. number 1 cow gives 1kg milk, number 2 gives 2 kg... number and so on up to number 25 that gives 25 kg per day. The farmer has 5 sons and he wants to distribute his cows to them: 7 to the first, 6 to the second and so on down to 3 to the last, however, the total quantity of milk produced should be the same: how can he distribute the cows?  Print the assignment of cows to sons (cow_assignments), as a list of 25 integers from 0 to 4.

Input data:

Decision variables: cow_assignments

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

# Parameters
num_cows = 25
num_sons = 5
milk_per_cow = list(range(1, num_cows + 1))
cows_per_son = [7, 6, 5, 4, 3]

total_milk = sum(milk_per_cow)  # Total milk produced by all cows
total_milk_per_son = total_milk // num_sons  # Total milk each son should get

# Decision variables
# Each cow is assigned to a son, represented by 0-4
cow_assignments = intvar(0, num_sons - 1, shape=num_cows)

# Constraints
model = Model()

# Each son gets a specific number of cows
for son in range(num_sons):
    model += sum(cow_assignments == son) == cows_per_son[son]

# The total milk production for each son is equal
for son in range(num_sons):
    model += sum(milk_per_cow[i] * (cow_assignments[i] == son) for i in range(num_cows)) == total_milk_per_son

# Solve
model.solve()

# Print the solution
solution = {"cow_assignments": cow_assignments.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Baker, Cooper, Fletcher, Miller, and Smith live on the first five floors of an apartment house. Baker does not live on the fifth floor. Cooper does not live on the first floor. Fletcher does not live on either the fifth or the first floor. Miller lives on a higher floor than does Cooper. Smith does not live on a floor adjacent to Fletcher’. Fletcher does not live on a floor adjacent to Cooper’s. They all live on different floors. Find the floors where these people live.  Print the floors where each person lives (B, C, F, M, S).

Input data:

Decision variables: M, C, F, B, S

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

# Decision Variables
B = intvar(1, 5)  # Baker
C = intvar(1, 5)  # Cooper
F = intvar(1, 5)  # Fletcher
M = intvar(1, 5)  # Miller
S = intvar(1, 5)  # Smith

# Constraints
model = Model()

model += B != 5  # Baker does not live on the fifth floor
model += C != 1  # Cooper does not live on the first floor
model += (F != 5) & (F != 1)  # Fletcher does not live on either the fifth or the first floor
model += M > C  # Miller lives on a higher floor than does Cooper
model += abs(S - F) != 1  # Smith does not live on a floor adjacent to Fletcher
model += abs(F - C) != 1  # Fletcher does not live on a floor adjacent to Cooper
model += AllDifferent([B, C, F, M, S])  # They all live on different floors

# Solve
model.solve()

# Print the solution
solution = {"B": B.value(), "C": C.value(), "F": F.value(), "M": M.value(), "S": S.value()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
A kid goes into a grocery store and buys four items. The cashier charges $7.11, the kid pays and is about to leave when the cashier calls the kid back, and says "Hold on, I multiplied the four items instead of adding them; I’ll try again; Hah, with adding them the price still comes to $7.11". What were the prices of the four items?  Print the prices of the four items (prices) in cents.

Input data:

Decision variables: prices

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

# Parameters
total_price = 711  # total price in cents
num_items = 4

# Decision variables (prices are considered in cents)
prices = intvar(1, total_price, shape=num_items)

# Constraints
model = Model()

# The sum of the prices in cents is equal to the total price in cents
model += sum(prices) == total_price

# The product of the prices should equal to the scaled total price in cents (to account for the multiplication)
model += np.prod(prices) == total_price * (100 ** (num_items - 1))

# Solve
model.solve()

# Print the solution
solution = {"prices": prices.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
A boy wants to give an apple to a girl. To get to her, he has to pass through five gates, each with a guard. He bribes each guard with half of his apples, plus one. The boy does not have a knife, therefore he gives the guard an integer number of apples. After he’s given the apple to the girl, he has no apples left.  Print a list of 6 numbers (apples), containing the number of apples before each gate, plus the number of apples after the last gate.

Input data:

Decision variables: apples

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

# Parameters
num_gates = 5

# Decision Variables
apples = intvar(0, 100, shape=num_gates + 1)  # the number of apples before each gate plus after the last gate

# Constraints
model = Model()

# The boy is left with no apples after giving the apple to the girl, so he has 1 apple after the last gate.
model += apples[-1] == 1

# At each guard, the boy gives half of his apples, plus one.
for i in range(1, num_gates + 1):
    has_before = apples[i - 1]
    has_after = apples[i]
    model += has_before == 2 * (has_after + 1)

# Solve
model.solve()

# Print the solution
solution = {"apples": apples.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Find a combination of 4 different numbers between 1 and 100, such that the sum of the squares of the two first numbers is equal to the sum of the squares of the other two numbers, i.e. a^2 + b^2 = c^2 + d^2 for some a, b, c, d in {1, 100}, a != b != c != d.  Print the numbers (a, b, c, d).

Input data:

Decision variables: b, d, c, a

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

range_min = 1
range_max = 100

# Decision variables
a, b, c, d = intvar(range_min, range_max, shape=4)

# Constraints
model = Model()

# Sum of squares of any two numbers is equal to the sum of squares of the other two numbers
model += (a**2 + b**2) == (c**2 + d**2)

# Constraints to ensure all variables are distinct
model += AllDifferent([a, b, c, d])

# Solve
model.solve()

# Print the solution
solution = {"a": a.value(), "b": b.value(), "c": c.value(), "d": d.value()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
At the hospital n people are on a waiting list for a kidney’s transplant. We have the information about the compatibility between these people as a directed graph: compatible[i] is the set of people to which i can donate. Given this information, we want to maximize the number of people that receive a new kidney: anyone who gives a kidney must receive one, and no person receives more than one kidney.  Print the transplants (transplants) as a list of lists, where transplants[i][j] is 1 if person i donates to person j, and 0 otherwise.

Input data:
num_people = 8  # number of people compatible = [  # 1-based indexing, compatible[i] is the list of people to which i can donate     [2, 3],     [1, 6],     [1, 4, 7],     [2],     [2],     [5],     [8],     [3] ]

Decision variables: transplants

CPMpy model:
# Data
num_people = 8  # number of people
compatible = [  # 1-based indexing, compatible[i] is the list of people to which i can donate
    [2, 3],
    [1, 6],
    [1, 4, 7],
    [2],
    [2],
    [5],
    [8],
    [3]
]
# End of data

# Import libraries
from cpmpy import *
import json

# Decision variables
transplants = boolvar(shape=(num_people, num_people))  # transplants[i][j] is True if i donates to j

# Model setup
model = Model()

# Constraints for the transplant pairs
for i in range(num_people):
    # Anyone who gives a kidney must receive one
    gives_kidney = sum(transplants[i, :]) >= 1
    receives_kidney = sum(transplants[:, i]) >= 1
    model += gives_kidney.implies(receives_kidney)

    # Each person can donate to at most one person and receive from at most one person
    can_donate_once = sum(transplants[i, :]) <= 1
    can_receive_once = sum(transplants[:, i]) <= 1
    model += can_donate_once & can_receive_once

    # Compatibility constraint: if i can't donate to j, then transplants[i][j] must be 0 (adjust for 0-based indexing)
    model += [transplants[i, j] == 0 for j in range(num_people) if j + 1 not in compatible[i]]

# Objective: maximize the number of transplants
model.maximize(sum(transplants))

# Solve
model.solve()

# Print the solution
solution = {"transplants": transplants.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
A magic square is an n x n grid (n != 2) such that each cell contains a different integer from 1 to n^2 and the sum of the integers in each row, column and diagonal is equal. Find a magic square for size 4, knowing that the sum of integers of each row, column and diagonal has to be equal to n(n^2+ 1)/2 (integer).  Print the magic square as a list of lists (square).

Input data:

Decision variables: square

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

# Parameters
n = 4  # size of the magic square
magic_sum = n * (n**2 + 1) // 2  # sum of each row, column and diagonal

# Decision Variables
square = intvar(1, n ** 2, shape=(n, n))  # the magic square

# Constraints
model = Model()

# All numbers in the magic square must be different
model += AllDifferent(square)

# The sum of the numbers in each row must be equal to the magic sum
for i in range(n):
    model += sum(square[i, :]) == magic_sum

# The sum of the numbers in each column must be equal to the magic sum
for j in range(n):
    model += sum(square[:, j]) == magic_sum

# The sum of the numbers in the main diagonal must be equal to the magic sum
model += sum(square[i, i] for i in range(n)) == magic_sum

# The sum of the numbers in the other diagonal must be equal to the magic sum
model += sum(square[i, n - 1 - i] for i in range(n)) == magic_sum

# Solve
model.solve()

# Print the solution
solution = {"square": square.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
In graph theory, an independent set is a set of vertices in a graph, no two of which are adjacent. A maximal independent set is an independent set that is not a subset of any other independent set. A graph may have many maximal independent sets of widely varying sizes: find a maximal independent set for the data provided. The data provides an array containing for each node of the graph the set of adjacent nodes.  Print whether each node is included in the maximal independent set (nodes).

Input data:
n = 8  # number of nodes in the graph adjacency_list = [  # adjacency list for each node in the graph     [2, 3, 7],     [1, 4, 8],     [1, 4, 5],     [2, 3, 6],     [3, 6, 7],     [4, 5, 8],     [1, 5, 8],     [2, 6, 7] ]

Decision variables: nodes

CPMpy model:
# Data
n = 8  # number of nodes in the graph
adjacency_list = [  # adjacency list for each node in the graph
    [2, 3, 7],
    [1, 4, 8],
    [1, 4, 5],
    [2, 3, 6],
    [3, 6, 7],
    [4, 5, 8],
    [1, 5, 8],
    [2, 6, 7]
]
# End of data

# Import libraries
from cpmpy import *
import json


# Create a binary decision variable for each node to indicate if it's included in the independent set
nodes = boolvar(shape=n)

# Model setup
model = Model()

# Constraint: No two adjacent nodes can both be in the independent set
for i, neighbors in enumerate(adjacency_list):
    for neighbor in neighbors:
        # Subtract 1 to adjust for 1-based indexing in the data
        neighbor_idx = neighbor - 1
        # Ensure that for every edge, at least one of its endpoints is not in the independent set
        model += ~(nodes[i] & nodes[neighbor_idx])

# Objective: Maximize the number of nodes in the independent set
model.maximize(sum(nodes))

# Solve
model.solve()

# Print the solution
solution = {"nodes": nodes.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Alice has to give Bob change of 199 euros. She has 6 different types of coins of different value ([1, 2, 5, 10, 25, 50]) and she has a certain number of coins of each value available ([20, 10, 15, 8, 4, 2]). How can the change be composed with the available coins minimizing the number of coins used?  Print the number of coins of each type to give to Bob (coin_counts).

Input data:

Decision variables: coin_counts

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

# Parameters
amount = 199  # amount of money to give to Bob
n = 6  # number of types of coins
types_of_coins = [1, 2, 5, 10, 25, 50]  # value of each type of coin
available_coins = [20, 10, 15, 8, 4, 2]  # number of available coins of each type

# Decision Variables
coin_counts = intvar(0, 20, shape=n)  # number of coins of each type to give to Bob

# Constraints
model = Model()

# The sum of the coins given to Bob must be equal to the amount of money to give him
model += sum(coin_counts[i] * types_of_coins[i] for i in range(n)) == amount

# The number of each type of coin given to Bob must not exceed the available coins
for i in range(n):
    model += coin_counts[i] <= available_coins[i]

# Objective: Minimize the total number of coins given to Bob
model.minimize(sum(coin_counts))

# Solve
model.solve()

# Print the solution
solution = {"coin_counts": coin_counts.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Consider the following scheduling problem. Imagine you are a highly-in- demand actor, who has been presented with offers to star in n different movie projects under development. Each offer comes specified with the first and last day of filming. To take the job, you must commit to being available throughout this entire period. Thus, you cannot simultaneously accept two jobs whose intervals overlap. For an artist such as yourself, the criteria for job acceptance is clear: you want to make as much money as possible. Because each of these films pays the same fee per film, this implies you seek the largest possible set of jobs (intervals) such that no two of them conflict with each other.  Input is a list of movies along with their first and last day of filming  Print the number of movies accepted (num_selected_movies) as well as which movies are accepted (selected_movies) as a list of 0s and 1s, where 1 indicates that the movie is selected and 0 indicates that it is not selected (in the order of the input list).

Input data:
movies = [  # title, start, end     ["Tarjan of the Jungle", 4, 13],     ["The Four Volume Problem", 17, 27],     ["The President's Algorist", 1, 10],     ["Steiner's Tree", 12, 18],     ["Process Terminated", 23, 30],     ["Halting State", 9, 16],     ["Programming Challenges", 19, 25],     ["Discrete Mathematics", 2, 7],     ["Calculated Bets", 26, 31] ]

Decision variables: in the order of the input list, selected_movies, num_selected_movies

CPMpy model:
# Data
movies = [  # title, start, end
    ["Tarjan of the Jungle", 4, 13],
    ["The Four Volume Problem", 17, 27],
    ["The President's Algorist", 1, 10],
    ["Steiner's Tree", 12, 18],
    ["Process Terminated", 23, 30],
    ["Halting State", 9, 16],
    ["Programming Challenges", 19, 25],
    ["Discrete Mathematics", 2, 7],
    ["Calculated Bets", 26, 31]
]
# End of data

# Import libraries
from cpmpy import *
import json

# Parameters
num_movies = len(movies)

# Decision Variables
selected_movies = boolvar(shape=num_movies, name="selected_movies")  # 1 if the movie is selected, 0 otherwise
num_selected_movies = sum(selected_movies)  # Number of selected movies

# Model
model = Model()

# Add constraint for non-overlapping movie schedules
for i in range(num_movies):
    for j in range(num_movies):
        # Check if the intervals overlap for each pair of movies
        if (i != j  # Different movies
                and movies[i][2] > movies[j][1]  # Movie i ends after movie j starts
                and movies[j][2] > movies[i][1]  # Movie j ends after movie i starts
        ):
            # Then, the movies cannot be selected together
            model += selected_movies[i] + selected_movies[j] <= 1

# Objective: Maximize the number of selected movies
model.maximize(num_selected_movies)

# Solve
model.solve()

# Print
solution = {"num_selected_movies": model.objective_value(),
            "selected_movies": selected_movies.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
There are 13 people. 4 of them are male. They randomly enter a room one at a time. Find a way that the males and females enter so that the ratio of females to males in the room at any one time is no greater than 7/3?  Print the sequence of people entering the room (sequence), where 0 represents male and 1 represents female.

Input data:

Decision variables: sequence

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

total_people = 13
num_males = 4

# Decision variable: 0 for male, 1 for female
sequence = boolvar(shape=total_people)

# Constraints
model = Model()

# Ensure exactly number of males and females
model += [sum(sequence) == total_people - num_males]

# Add constraints for the ratio at each point in the sequence
for i in range(1, total_people):
    total_females_so_far = sum(sequence[:i])
    total_males_so_far = i - sum(sequence[:i])
    # Number of females to males is no greater than 7/3, or 3 times the females is less than or equal to 7 times the males
    model += (3 * total_females_so_far) <= (7 * total_males_so_far)

# Solve
model.solve()

# Print the solution
solution = {"sequence": sequence.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Out of the set of integers 1,...,100 you are given ten different integers ([81 21 79  4 29 70 28 20 14  7]). From this set A of ten integers you can always find two disjoint non-empty subsets, S and T, such that the sum of elements in S equals the sum of elements in T. Note: S union T does not need to be all ten elements of A. Find sets S and T for the given set A.  Print which elements are in S (in_S) and which elements are in T (in_T), with 2 lists of length 10, where 1 means that the element is in the subset and 0 means that it is not.

Input data:

Decision variables: in_S, in_T

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

# Parameters
A = [81, 21, 79, 4, 29, 70, 28, 20, 14, 7]

# Decision variables: 1 if an element is in the subset, 0 otherwise
in_S = boolvar(shape=len(A))
in_T = boolvar(shape=len(A))

# Model setup
model = Model()

# Constraint: sum of elements in S equals sum of elements in T
model += (sum(in_S * A) == sum(in_T * A))

# S and T are disjoint, so there is no element that is in both S and T
model += (sum(in_S * in_T) == 0)

# S and T are non-empty
model += (sum(in_S) > 0)
model += (sum(in_T) > 0)

# Solve
model.solve()

# Print the solution
solution = {"in_S": in_S.value().tolist(), "in_T": in_T.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
A bank van had several bags of coins, each containing either 16, 17, 23, 24, 39, or 40 coins (there are multiple bags of the same kind). While the van was parked on the street, thieves stole some bags. A total of 100 coins were lost. It is required to find how many bags were stolen for each type of coin bag.  Print the number of bags stolen for each type of coins (bags).

Input data:

Decision variables: bags

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

total_coins_lost = 100
coin_numbers = [16, 17, 23, 24, 39, 40]

# Decision variables
# The number of bags stolen for each type of coins
bags = intvar(0, total_coins_lost, shape=len(coin_numbers))

# Constraints
model = Model()

# The total number of coins lost is equal to the sum of the coins in the stolen bags
model += sum([bags[i] * coin_numbers[i] for i in range(len(coin_numbers))]) == total_coins_lost

# Solve
model.solve()

# Print the solution
solution = {"bags": bags.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Following a robbery at Sparkles the Jeweller’s, Inspector Korner of the Yard interviewed six of the usual suspects. He knew that the getaway car had been barely big enough to hold two, so he reckoned that at least four of them were innocent - but which ones? He also supposed that the innocent ones would tell the truth, while the guilty one or ones would lie. What they actually said was: - ARTIE: "It wasn't me." - BILL: "Crackitt was in it up to his neck." - CRACKITT: "No I wasn't." - DODGY: "If Crackitt did it, Bill did it with him." - EDGY: "Nobody did it alone." - FINGERS: "That’s right: it was Artie and Dodgy together." If the good inspector’s suppositions were correct, who is guilty?  Print whether each suspect is guilty or not (artie, bill, crackitt, dodgy, edgy, fingers).

Input data:

Decision variables: dodgy, fingers, edgy, bill, artie, crackitt

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

# Decision Variables for each suspect representing if they are guilty
artie = boolvar(name="Artie")
bill = boolvar(name="Bill")
crackitt = boolvar(name="Crackitt")
dodgy = boolvar(name="Dodgy")
edgy = boolvar(name="Edgy")
fingers = boolvar(name="Fingers")
suspects = [artie, bill, crackitt, dodgy, edgy, fingers]

# Constraints
model = Model()

# At most two are guilty because the getaway car was small
model += sum(suspects) <= 2

# Statement Constraints; if the suspect is guilty, they are lying, so their statement is false

# Artie: "It wasn't me."
artie_statement = ~artie
model += artie == ~artie_statement

# Bill: "Crackitt was in it up to his neck."
bill_statement = crackitt
model += bill == ~bill_statement

# Crackitt: "No I wasn't."
crackitt_statement = ~crackitt
model += crackitt == ~crackitt_statement

# Dodgy: "If Crackitt did it, Bill did it with him."
dodgy_statement = crackitt.implies(bill)
model += dodgy == ~dodgy_statement

# Edgy: "Nobody did it alone."
edgy_statement = sum(suspects) > 1
model += edgy == ~edgy_statement

# Fingers: "That’s right: it was Artie and Dodgy together."
fingers_statement = artie & dodgy
model += fingers == ~fingers_statement

# Solve
model.solve()

# Print the solution
solution = {
    "artie": int(artie.value()),
    "bill": int(bill.value()),
    "crackitt": int(crackitt.value()),
    "dodgy": int(dodgy.value()),
    "edgy": int(edgy.value()),
    "fingers": int(fingers.value())
}
print(json.dumps(solution))
# End of CPMPy script