Constructing a $3 \times 3$ Magic Square
The $python$-$constraint$ library is a powerful tool for solving constraint satisfaction problems (CSPs) in $Python$.
It allows you to define variables, domains, and constraints, then finds solutions that satisfy all the constraints.
While the basic usage is straightforward, here are some unconventional or “curious” ways to use $python$-$constraint$ that showcase its flexibility.
Magic Square
A $magic$ $square$ is a grid where the sum of the numbers in each row, column, and diagonal is the same.
This is another interesting constraint satisfaction problem that can be solved with $python$-$constraint$.
1 | from constraint import Problem, AllDifferentConstraint |
Explanation
This $Python$ code uses the $python$-$constraint$ library to solve a constraint satisfaction problem, specifically constructing a $ 3 \times 3 $ magic square.
In a magic square, all rows, columns, and diagonals must sum to the same value, known as the “$magic$ $sum$.”
For a $3 \times 3$ grid with the numbers $1$ to $9$, this magic sum is $15$.
Step-by-Step Explanation:
Importing Required Modules:
1
from constraint import Problem, AllDifferentConstraint
The
Problemclass is used to define and solve the constraint satisfaction problem (CSP).
TheAllDifferentConstraintensures that all variables (the cells in the magic square) take different values.Creating the Problem Instance:
1
problem = Problem()
A
Problemobject is instantiated to manage the variables and constraints of the problem.Defining Variables:
1
2variables = [(row, col) for row in range(3) for col in range(3)]
problem.addVariables(variables, range(1, 10))The variables represent each cell in the $3 \times 3$ grid, identified by their row and column indices (e.g.,
(0, 0)for the top-left cell).
Each cell can take a value from $1$ to $9$.Adding the All-Different Constraint:
1
problem.addConstraint(AllDifferentConstraint(), variables)
This constraint ensures that all cells in the magic square have different values.
In other words, no two cells can have the same number.Defining the Magic Sum:
1
magic_sum = 15
The sum of each row, column, and diagonal in the magic square must equal $15$, which is the “$magic$ $sum$” for a $3 \times 3$ magic square using numbers $1$ to $9$.
Adding Row Constraints:
1
2for row in range(3):
problem.addConstraint(lambda *args: sum(args) == magic_sum, [(row, col) for col in range(3)])This loop adds constraints for each row in the grid, ensuring that the sum of the numbers in each row equals $15$.
Adding Column Constraints:
1
2for col in range(3):
problem.addConstraint(lambda *args: sum(args) == magic_sum, [(row, col) for row in range(3)])This loop adds constraints for each column in the grid, ensuring that the sum of the numbers in each column equals $15$.
Adding Diagonal Constraints:
1
2problem.addConstraint(lambda *args: sum(args) == magic_sum, [(i, i) for i in range(3)])
problem.addConstraint(lambda *args: sum(args) == magic_sum, [(i, 2 - i) for i in range(3)])These lines add constraints for the two diagonals of the magic square.
The first constraint ensures that the main diagonal (top-left to bottom-right) sums to $15$, and the second ensures that the anti-diagonal (top-right to bottom-left) sums to $15$.Solving the Problem:
1
solution = problem.getSolution()
The
getSolution()method attempts to find a solution that satisfies all the constraints.
If a solution is found, it is returned as a dictionary, where each key is a cell (e.g.,(0, 0)) and each value is the number assigned to that cell.Printing the Solution:
1
2
3
4
5if solution:
for row in range(3):
print([solution[(row, col)] for col in range(3)])
else:
print("No solution found.")If a solution is found, the code prints the magic square in a $3 \times 3$ grid format.
If no solution is found, it prints “No solution found.”
Summary:
This code constructs a $3 \times 3$ magic square where each number from $1$ to $9$ is used exactly once, and the sum of the numbers in each row, column, and diagonal equals $15$.
By defining the problem as a set of constraints and solving it with the python-constraint library, the code finds a valid configuration for the magic square.
Output
[Output]
1 | [6, 1, 8] |
The result displayed represents a $3 \times 3$ magic square.
A magic square is a grid in which the numbers in each row, column, and diagonal all add up to the same value, known as the “$magic$ $sum$.”
For a $3 \times 3$ magic square using the numbers $1$ to $9$, this sum is $15$.
Breakdown of the Result:
First Row:
[6, 1, 8]
Sum:6 + 1 + 8 = 15Second Row:
[7, 5, 3]
Sum:7 + 5 + 3 = 15Third Row:
[2, 9, 4]
Sum:2 + 9 + 4 = 15
Column Sums:
- First Column:
6 + 7 + 2 = 15 - Second Column:
1 + 5 + 9 = 15 - Third Column:
8 + 3 + 4 = 15
Diagonal Sums:
- Main Diagonal (Top-Left to Bottom-Right):
6 + 5 + 4 = 15 - Anti-Diagonal (Top-Right to Bottom-Left):
8 + 5 + 2 = 15
Conclusion:
This $3 \times 3$ grid is a valid magic square.
Every row, column, and diagonal sums to $15$, satisfying the conditions of the magic square.
The numbers $1$ to $9$ are used exactly once, and the constraints of the problem have been correctly applied to generate this solution.
















