kostis-init/CP-Bench huggingface dataset:
Problem description:
Select a set of workers to perform all the tasks, while minimizing the cost. Each worker can perform certain tasks and has a hiring cost. Ensure that all tasks are performed.  Print the total cost (total_cost) and whether each worker is selected (workers) as a list of 0/1 values.

Input data:
nb_workers = 32  # Number of workers num_tasks = 15  # Number of tasks Qualified = [  # Which worker is qualified for each task (1-based indexing)     [1, 9, 19, 22, 25, 28, 31],     [2, 12, 15, 19, 21, 23, 27, 29, 30, 31, 32],     [3, 10, 19, 24, 26, 30, 32], [4, 21, 25, 28, 32],     [5, 11, 16, 22, 23, 27, 31], [6, 20, 24, 26, 30, 32],     [7, 12, 17, 25, 30, 31], [8, 17, 20, 22, 23],     [9, 13, 14, 26, 29, 30, 31], [10, 21, 25, 31, 32],     [14, 15, 18, 23, 24, 27, 30, 32], [18, 19, 22, 24, 26, 29, 31],     [11, 20, 25, 28, 30, 32], [16, 19, 23, 31],     [9, 18, 26, 28, 31, 32]] Cost = [  # Cost of hiring each worker     1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,     5, 6, 6, 6, 7, 8, 9 ]

Decision variables: total_cost, workers

CPMpy model:
# Data
nb_workers = 32  # Number of workers
num_tasks = 15  # Number of tasks
Qualified = [  # Which worker is qualified for each task (1-based indexing)
    [1, 9, 19, 22, 25, 28, 31],
    [2, 12, 15, 19, 21, 23, 27, 29, 30, 31, 32],
    [3, 10, 19, 24, 26, 30, 32], [4, 21, 25, 28, 32],
    [5, 11, 16, 22, 23, 27, 31], [6, 20, 24, 26, 30, 32],
    [7, 12, 17, 25, 30, 31], [8, 17, 20, 22, 23],
    [9, 13, 14, 26, 29, 30, 31], [10, 21, 25, 31, 32],
    [14, 15, 18, 23, 24, 27, 30, 32], [18, 19, 22, 24, 26, 29, 31],
    [11, 20, 25, 28, 30, 32], [16, 19, 23, 31],
    [9, 18, 26, 28, 31, 32]]
Cost = [  # Cost of hiring each worker
    1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,
    5, 6, 6, 6, 7, 8, 9
]
# End of data

# Import libraries
from cpmpy import *
import json

# Parameters
Workers = list(range(nb_workers))
Tasks = list(range(num_tasks))

#
# variables
#
workers = boolvar(shape=nb_workers, name="workers")  # 1 if the worker is hired, 0 otherwise
total_cost = intvar(0, nb_workers * sum(Cost), name="total_cost")  # Total cost of hiring the workers

model = Model(minimize=total_cost)

#
# constraints
#
model += [total_cost == sum(workers * Cost)]

for j in Tasks:
    # Sum the cost for hiring the qualified workers
    # (also, make 0-base)
    model += [sum([workers[c - 1] for c in Qualified[j]]) >= 1]

# Solve the model
model.solve()

# Print the solution
solution = {"total_cost": total_cost.value(), "workers": workers.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
We are to complete the puzzle       1   2   3   4   5    +---+---+---+---+---+       Given the list of words:  1 | 1 |   | 2 |   | 3 |             AFT     LASER    +---+---+---+---+---+             ALE     LEE  2 | # | # |   | # |   |             EEL     LINE    +---+---+---+---+---+             HEEL    SAILS  3 | # | 4 |   | 5 |   |             HIKE    SHEET    +---+---+---+---+---+             HOSES   STEER  4 | 6 | # | 7 |   |   |             KEEL    TIE    +---+---+---+---+---+             KNOT  5 | 8 |   |   |   |   |    +---+---+---+---+---+  6 |   | # | # |   | # |       The numbers 1,2,3,4,5,6,7,8 in the crossword    +---+---+---+---+---+       puzzle correspond to the words                                that will start at those locations.   Print the selected words (E) as a list of 8 integers starting from 0. Assume that the words are first sorted starting from the longest word and then alphabetically. So, word 0 corresponds to HOSES, ..., word 14 corresponds to TIE.

Input data:

Decision variables: E

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

a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
f = 6;
g = 7;
h = 8;
i = 9;
j = 10;
k = 11;
l = 12;
m = 13;
n = 14;
o = 15;
p = 16;
q = 17;
r = 18;
s = 19;
t = 20;
u = 21;
v = 22;
w = 23;
x = 24;
y = 25;
z = 26;

AA = [
    [h, o, s, e, s],  # HOSES
    [l, a, s, e, r],  # LASER
    [s, a, i, l, s],  # SAILS
    [s, h, e, e, t],  # SHEET
    [s, t, e, e, r],  # STEER
    [h, e, e, l, 0],  # HEEL
    [h, i, k, e, 0],  # HIKE
    [k, e, e, l, 0],  # KEEL
    [k, n, o, t, 0],  # KNOT
    [l, i, n, e, 0],  # LINE
    [a, f, t, 0, 0],  # AFT
    [a, l, e, 0, 0],  # ALE
    [e, e, l, 0, 0],  # EEL
    [l, e, e, 0, 0],  # LEE
    [t, i, e, 0, 0]  # TIE
]
word_len = 5
num_words = len(AA)

num_overlapping = 12
overlapping = [
    [0, 2, 1, 0],  # s
    [0, 4, 2, 0],  # s

    [3, 1, 1, 2],  # i
    [3, 2, 4, 0],  # k
    [3, 3, 2, 2],  # e

    [6, 0, 1, 3],  # l
    [6, 1, 4, 1],  # e
    [6, 2, 2, 3],  # e

    [7, 0, 5, 1],  # l
    [7, 2, 1, 4],  # s
    [7, 3, 4, 2],  # e
    [7, 4, 2, 4]  # r
]

A = intvar(0, 26, shape=(num_words, word_len), name="A")

n = 8
E = intvar(0, num_words, shape=n, name="E")  # The selected words for each slot

model = Model()

for I in range(num_words):
    for J in range(word_len):
        model += [A[I, J] == AA[I][J]]

model += [AllDifferent(E)]

for I in range(num_overlapping):
    model += [A[E[overlapping[I][0]], overlapping[I][1]] == A[E[overlapping[I][2]], overlapping[I][3]]]

model.solve()

# Print the solution
solution = {"E": E.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Cryptarithmetic puzzle, solve the operation:    B A I J J A J I I A H F C F E B B J E A    + D H F G A B C D I D B I F F A G F E J E    -----------------------------------------    = G J E G A C D D H F A F J B F I H E E F      where all letters are distinct digits.  Print the number of each letter (A, B, C, D, E, F, G, H, I, J).

Input data:

Decision variables: H, D, J, G, E, C, I, F, A, B

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

model = Model()

# variables
LD = intvar(0, 9, shape=10, name="LD")
A, B, C, D, E, F, G, H, I, J = LD

Sr1 = intvar(0, 1, name="Sr1")
Sr2 = intvar(0, 1, name="Sr2")

#
# constraints
#
model += [AllDifferent(LD)]
model += [B >= 1]
model += [D >= 1]
model += [G >= 1]

model += [A + 10 * E + 100 * J + 1000 * B + 10000 * B + 100000 * E +
          1000000 * F + E + 10 * J + 100 * E + 1000 * F + 10000 * G +
          100000 * A + 1000000 * F == F + 10 * E + 100 * E + 1000 * H +
          10000 * I + 100000 * F + 1000000 * B + 10000000 * Sr1]

model += [C + 10 * F + 100 * H + 1000 * A + 10000 * I + 100000 * I +
          1000000 * J + F + 10 * I + 100 * B + 1000 * D + 10000 * I +
          100000 * D + 1000000 * C + Sr1 == J + 10 * F + 100 * A + 1000 * F +
          10000 * H + 100000 * D + 1000000 * D + 10000000 * Sr2]

model += [A + 10 * J + 100 * J + 1000 * I + 10000 * A + 100000 * B + B +
          10 * A + 100 * G + 1000 * F + 10000 * H + 100000 * D + Sr2 == C +
          10 * A + 100 * G + 1000 * E + 10000 * J + 100000 * G]

# Solve the model
model.solve()

# Print the solution
solution = {"A": A.value(), "B": B.value(), "C": C.value(), "D": D.value(), "E": E.value(), "F": F.value(),
            "G": G.value(), "H": H.value(), "I": I.value(), "J": J.value()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Generate a random 18-hole golf course where each hole has a length of 3, 4, or 5, and the total length of the course is 72.  Print the lengths of the holes (holes).

Input data:

Decision variables: holes

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

# Parameters
num_holes = 18  # Number of holes
total_length = 72  # Total length of the course
hole_lengths = [3, 4, 5]  # Possible lengths for each hole

# Decision variables
holes = intvar(3, 5, shape=num_holes, name="holes")  # Lengths of the holes

# Model
model = Model([
    sum(holes) == total_length
])

# Solve the model
model.solve()

# Print the solution
solution = {"holes": holes.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
A side show at Coney Island is described as follows: "There were ten little dummies which you were to knock over with baseballs. The man said: 'Take as many throws as you like at a cent apiece and stand as close as you please. Add up the numbers on all the men that you knock down and when the sum amounts to exactly fifty, neither more nor less you get a genuine 25 cent Maggie Cline cigar with a gold band around it.'" The numbers on the ten dummies were 15, 9, 30, 21, 19, 3, 12, 6, 25, 27.  Print the dummies that are knocked over (dummies).

Input data:

Decision variables: dummies

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

# Parameters
target_sum = 50  # Target sum to achieve
values = [15, 9, 30, 21, 19, 3, 12, 6, 25, 27]  # Numbers on the dummies
n = len(values)

# Decision variables
dummies = boolvar(shape=n, name="dummies")  # Boolean array to indicate which dummies are knocked over

# Model
model = Model([
    sum([values[i] * dummies[i] for i in range(n)]) == target_sum
])

# Solve the model
model.solve()

# Print the solution
solution = {"dummies": dummies.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Three coins lie on a table in the order tails, heads ,tails. In precisely three moves make them face either all heads or all tails.  Print the steps (steps) to make all coins face either all heads or all tails.

Input data:
num_moves = 3  # Number of moves to make all coins face either all heads or all tails init = [1, 0, 1]  # Initial configuration of the coins

Decision variables: steps

CPMpy model:
# Data
num_moves = 3  # Number of moves to make all coins face either all heads or all tails
init = [1, 0, 1]  # Initial configuration of the coins
# End of data

# Import libraries
from cpmpy import *
import json

# Parameters
n = len(init)

# decision variables
# 0: heads, 1: tails
steps = boolvar(shape=(num_moves + 1, n), name="x")  # The steps to make all coins face either all heads or all tails

#  last line, either all heads or all tails
last_val = sum(steps[num_moves])

model = Model([
    steps[0] == init,
    # Exactly one difference per move
    [sum([steps[m, j] != steps[m - 1, j] for j in range(n)]) == 1 for m in range(1, num_moves + 1)],
    # last line: either all heads of all tails
    ((last_val == 0) | (last_val == n)),
])

# Solve the model
model.solve()

# Print the solution
solution = {"steps": steps.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Given a collection of integers, find three elements that sum to zero.  Print whether each element is selected (indices).

Input data:
nums = [-1, 6, 8, 9, 10, -100, 78, 0, 1]  # Collection of integers

Decision variables: indices

CPMpy model:
# Data
nums = [-1, 6, 8, 9, 10, -100, 78, 0, 1]  # Collection of integers
# End of data

# Import libraries
from cpmpy import *
import json

# Parameters
n = len(nums)
m = 3  # The number of elements that should sum to 0

# Decision variables
indices = boolvar(shape=n, name="indices")  # Boolean array to indicate which elements are selected

# Model
model = Model([
    sum([nums[i] * indices[i] for i in range(n)]) == 0,
    sum(indices) == m
])

# Solve the model
model.solve()

# Print the solution
solution = {"indices": indices.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Given a target number of beers, find the closest combination of 7-packs and 13-packs that meets or exceeds the target.  Print the counts of 7-packs and 13-packs used (counts).

Input data:
target = 20  # Target number of beers

Decision variables: counts

CPMpy model:
# Data
target = 20  # Target number of beers
# End of data

# Import libraries
from cpmpy import *
import json
import builtins

# Parameters
n = 2  # Number of pack sizes
packs = [7, 13]  # Pack sizes
max_val = target * 2  # Arbitrary max limit of pack counts

# Decision variables
counts = intvar(0, max_val, shape=n, name="counts")  # Count of each pack size used
total = intvar(0, max_val * n, name="total")  # Total number of beers

# Model
model = Model([
    total == (counts * packs).sum(),
    total >= target,
])

# Objective
model.minimize(total)

# Solve the model
model.solve()

# Print the solution
solution = {"counts": counts.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Progress City is considering a mass-transit bus system to reduce in-city driving. The goal is to determine the minimum number of buses required to meet the transportation needs throughout the day. The demand for buses is approximated as constant over successive 4-hour intervals. Each bus can operate only 8 successive hours a day.  We need to ensure that the number of buses available in each 4-hour interval meets the demand for that interval. Also, due to overlapping shifts, the schedule must account for buses transitioning between intervals.  Print the number of buses scheduled in each time slot (x).

Input data:
demands = [4, 8, 10, 7, 12, 4]  # Demand for buses in each 4-hour time slot

Decision variables: x

CPMpy model:
# Data
demands = [4, 8, 10, 7, 12, 4]  # Demand for buses in each 4-hour time slot
# End of data

# Import libraries
from cpmpy import *
import json

# Parameters
slots = len(demands)

# Decision Variables
# x[i] represents the number of buses scheduled to start working in the i-th 4-hour slot
x = intvar(0, sum(demands), shape=slots, name="x")

# Model the constraints
# Each bus operates for 8 hours, so it covers two consecutive 4-hour slots
constraints = []
for i in range(slots):
    # The number of buses covering the i-th and (i+1)-th slot should meet the demand of the (i+1)-th slot
    constraints.append(x[i] + x[(i + 1) % slots] >= demands[(i + 1) % slots])

# Create the model with constraints
model = Model(constraints)

# Objective: Minimize the total number of buses used
model.minimize(sum(x))

# Solve the model
model.solve()

# Print the solution
solution = {"x": x.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Job Shop Scheduling Problem  One common scheduling problem is the job shop, in which multiple jobs are processed on several machines.  Each job consists of a sequence of tasks, which must be performed in a given order, and each task must be processed on a specific machine. For example, the job could be the manufacture of a single consumer item, such as an automobile. The problem is to schedule the tasks on the machines so as to minimize the length of the schedule—the time it takes for all the jobs to be completed.  There are several constraints for the job shop problem: - No task for a job can be started until the previous task for that job is completed. - A machine can only work on one task at a time. - A task, once started, must run to completion.  Print the optimal makespan (makespan), which is the total time taken to complete all jobs.

Input data:
jobs_data = [  # (job_id, task_id) -> (machine_id, duration)     [(0, 3), (1, 2), (2, 2)],  # Job 0     [(0, 2), (2, 1), (1, 4)],  # Job 1     [(1, 4), (2, 3)]           # Job 2 ]

Decision variables: makespan

CPMpy model:
# Data
jobs_data = [  # (job_id, task_id) -> (machine_id, duration)
    [(0, 3), (1, 2), (2, 2)],  # Job 0
    [(0, 2), (2, 1), (1, 4)],  # Job 1
    [(1, 4), (2, 3)]           # Job 2
]
# End of data

# Import libraries
from cpmpy import *
import json
from itertools import combinations
import builtins  # To access the original built-in functions (because of the import * above)

# Extract job data
n_jobs = len(jobs_data)
n_tasks = builtins.sum(len(job) for job in jobs_data)
machines = set(task[0] for job in jobs_data for task in job)
n_machines = len(machines)

# Create variables for start and end times
max_duration = builtins.sum(task[1] for job in jobs_data for task in job)
max_tasks_per_job = builtins.max(len(job) for job in jobs_data)
start_times = intvar(0, max_duration, shape=(n_jobs, max_tasks_per_job), name="start_times")
end_times = intvar(0, max_duration, shape=(n_jobs, max_tasks_per_job), name="end_times")
makespan = intvar(0, max_duration, name="makespan")

# Create the model
model = Model()

# Add constraints for each task
for job_id, job in enumerate(jobs_data):
    for task_id, (machine, duration) in enumerate(job):
        model += (end_times[job_id, task_id] == start_times[job_id, task_id] + duration)

        # No task can start before the previous one ends
        if task_id > 0:
            model += (start_times[job_id, task_id] >= end_times[job_id, task_id - 1])

# Add machine constraints
for machine in machines:
    machine_tasks = [(job_id, task_id) for job_id, job in enumerate(jobs_data) for task_id, (m, duration) in enumerate(job) if m == machine]
    for (job1, task1), (job2, task2) in combinations(machine_tasks, 2):
        model += (start_times[job1, task1] >= end_times[job2, task2]) | (start_times[job2, task2] >= end_times[job1, task1])

# Objective: Minimize makespan
model += (makespan == max(end_times.flatten()))
model.minimize(makespan)

# Solve the model
model.solve()

# Print the solution
solution = {
    "makespan": makespan.value()
}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
A hiker is planning a trip and needs to decide which items to take in their backpack. Each item has a certain value and weight, and the hiker wants to maximize the total value of the items in the backpack without exceeding the weight capacity of the backpack.  Print which items to take (x).

Input data:
values = [4, 2, 3, 7, 1]  # Values of the items weights = [3, 1, 2, 5, 4]  # Weights of the items capacity = 7  # Capacity of the knapsack

Decision variables: x

CPMpy model:
# Data
values = [4, 2, 3, 7, 1]  # Values of the items
weights = [3, 1, 2, 5, 4]  # Weights of the items
capacity = 7  # Capacity of the knapsack
# End of data

# Import libraries
from cpmpy import *
import json

# Construct the model
x = boolvar(shape=len(values), name="x")

model = Model(
    sum(x * weights) <= capacity,
    maximize=sum(x * values)
)

# Solve the model
model.solve()

# Print the solution
solution = {
    "x": x.value().tolist()
}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
Minesweeper rules are very simple. The board is divided into cells, with mines randomly distributed. To win, you need to open all the cells. The number on a cell shows the number of mines adjacent to it. Using this information, you can determine cells that are safe, and cells that contain mines. Cells suspected of being mines can be marked with a flag using the right mouse button.  The task is to determine which 'X' fields contain mines based on the provided numerical clues.  Print whether each cell is a mine or not (mines).

Input data:
X = -1 game_data = [  # 0-8: number of mines around, -1: not opened     [2, 3, X, 2, 2, X, 2, 1],     [X, X, 4, X, X, 4, X, 2],     [X, X, X, X, X, X, 4, X],     [X, 5, X, 6, X, X, X, 2],     [2, X, X, X, 5, 5, X, 2],     [1, 3, 4, X, X, X, 4, X],     [0, 1, X, 4, X, X, X, 3],     [0, 1, 2, X, 2, 3, X, 2] ]

Decision variables: mines

CPMpy model:
# Data
X = -1
game_data = [  # 0-8: number of mines around, -1: not opened
    [2, 3, X, 2, 2, X, 2, 1],
    [X, X, 4, X, X, 4, X, 2],
    [X, X, X, X, X, X, 4, X],
    [X, 5, X, 6, X, X, X, 2],
    [2, X, X, X, 5, 5, X, 2],
    [1, 3, 4, X, X, X, 4, X],
    [0, 1, X, 4, X, X, X, 3],
    [0, 1, 2, X, 2, 3, X, 2]
]
# End of data

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

# Parameters
game = np.array(game_data)
rows, cols = game.shape
S = [-1, 0, 1]  # for the neighbors of a cell

# Decision Variables
mines = boolvar(shape=game.shape)  # True: mine, False: not mine

model = Model()
for (r, c), val in np.ndenumerate(game):
    if val != X:
        # This cell cannot be a mine
        model += mines[r, c] == 0
        # Count neighbors
        model += (sum(mines[r + a, c + b]
                      for a in S for b in S
                      if 0 <= r + a < rows and 0 <= c + b < cols and (a, b) != (0, 0))
                  == val)

# Solve
model.solve()

# Print
solution = {"mines": mines.value().tolist()}
print(json.dumps(solution))
# End of CPMPy script
Problem description:
N-Puzzle Problem  The N-Puzzle is a classic sliding puzzle game where the goal is to move tiles on a grid to achieve a specific end configuration. The puzzle consists of a grid with \( n+1 \) tiles, one of which is empty. The objective is to trace the steps to the original picture by moving the tiles into their correct positions.  Input is the start and end state of the puzzle, along with the number of steps to the solution.  Print the state of the puzzle at each step (steps) as a list of N integer 2-dimensional matrices.

Input data:
N = 20  # Number of steps to the solution puzzle_start = [  # Start state of the puzzle, 0 represents the empty tile     [0, 3, 6],     [2, 4, 8],     [1, 7, 5] ]  puzzle_end = [  # End state of the puzzle     [1, 2, 3],     [4, 5, 6],     [7, 8, 0] ]

Decision variables: steps

CPMpy model:
# Data
N = 20  # Number of steps to the solution
puzzle_start = [  # Start state of the puzzle, 0 represents the empty tile
    [0, 3, 6],
    [2, 4, 8],
    [1, 7, 5]
]

puzzle_end = [  # End state of the puzzle
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 0]
]
# End of data

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


def n_puzzle(puzzle_start, puzzle_end, N):

    m = Model()

    (dim,dim2) = puzzle_start.shape
    assert (dim == dim2), "puzzle needs square shape"
    n = dim*dim2 - 1  # e.g. an 8-puzzle

    # State of puzzle at every step
    x = intvar(0,n, shape=(N,dim,dim), name="x")

    # Start state constraint
    m += (x[0] == puzzle_start)

    # End state constraint
    m += (x[-1] == puzzle_end)

    # define neighbors = allowed moves for the '0'
    def neigh(i,j):
        # same, left,right, down,up, if within bounds
        for (rr, cc) in [(0,0),(-1,0),(1,0),(0,-1),(0,1)]:
            if 0 <= i+rr and i+rr < dim and 0 <= j+cc and j+cc < dim:
                yield (i+rr,j+cc)

    # Transition: define next based on prev + invariants
    def transition(m, prev_x, next_x):
        # for each position, determine its reachability
        for i in range(dim):
            for j in range(dim):
                m += (next_x[i,j] == 0).implies(any(prev_x[r,c] == 0 for r,c in neigh(i,j)))

        # Invariant: in each step, all cells are different
        m += AllDifferent(next_x)

        # Invariant: only the '0' position can move
        m += ((prev_x == 0) | (next_x == 0) | (prev_x == next_x))

    # apply transitions (0,1) (1,2) (2,3) ...
    for i in range(1, N):
        transition(m, x[i-1], x[i])

    return (m,x)

# Example usage
model, steps = n_puzzle(np.array(puzzle_start), np.array(puzzle_end), N)
model.solve()

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