-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
113 lines (95 loc) · 2.7 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "algo_x.h"
#include <stdio.h>
#include <stdlib.h>
// An example program using the library to solve the N queens problem
#define DEFAULT_PROBLEM_SIZE 7
// Get constraints for placing queen on field (x,y) with boardsize 'size'
struct constraint* get_queens_constraints(int x, int y, int size);
void destroy_constraint(struct constraint* constraint);
// Add all relevant constraints to the matrix
void init_matrix(Matrix* matrix, int num_queens);
int solve_nqueens(int num_queens);
int main(int argc, char** argv)
{
int num_queens = DEFAULT_PROBLEM_SIZE;
if (argc == 2) {
num_queens = atoi(argv[1]);
}
if (num_queens < 2) {
printf("num_queens must be at least 2.\n");
return EXIT_FAILURE;
}
printf("Board size per dimension / # queens: %d\n", num_queens);
int result = solve_nqueens(num_queens);
printf("Result: %d\n", result);
return EXIT_SUCCESS;
}
struct constraint* get_queens_constraints(int x, int y, int size)
{
struct constraint* constraint = malloc(sizeof(struct constraint));
if (!constraint)
return NULL;
constraint->length = 4;
int row = x;
int col = y + size;
int diagonal = x + y + (2 * size - 1);
int rev_diag = (size - 1 - x + y) + (4 * size - 4);
bool drop_diagonal = (diagonal <= (2 * size - 1) || diagonal > 4 * size - 4);
bool drop_rev = (rev_diag < (4 * size - 3) || rev_diag > (6 * size - 7));
if (drop_rev) {
constraint->length--;
}
if (drop_diagonal) {
constraint->length--;
}
constraint->array = malloc(sizeof(int) * constraint->length);
if (!constraint->array) {
free(constraint);
return NULL;
}
constraint->array[0] = row;
constraint->array[1] = col;
if (drop_rev) {
if (!drop_diagonal)
constraint->array[2] = diagonal;
} else {
if (drop_diagonal) {
constraint->array[2] = rev_diag;
} else {
constraint->array[2] = diagonal;
constraint->array[3] = rev_diag;
}
}
return constraint;
}
void destroy_constraint(struct constraint* constraint)
{
if (constraint)
free(constraint->array);
free(constraint);
}
void init_matrix(Matrix* matrix, int num_queens)
{
for (int i = 0; i < num_queens; i++) {
for (int j = 0; j < num_queens; j++) {
struct constraint* constraint = get_queens_constraints(i, j, num_queens);
if (!constraint)
continue;
add_constraints(constraint, matrix);
destroy_constraint(constraint);
}
}
}
int solve_nqueens(int num_queens)
{
// columns && rows
int num_primaries = 2 * num_queens;
// diagonals && reverse diagonals
int num_secondaries = 2 * (2 * num_queens - 3);
// construct matrix
Matrix* matrix = get_matrix(num_primaries, num_secondaries);
init_matrix(matrix, num_queens);
int solutions = algorithm_x(matrix);
destroy_matrix(matrix);
return solutions;
}