为了完成一个大学作业,我正在实现一个数独求解器。实现的一部分是方法neighbors,它给出一个cell(x)计算它的邻居。也就是说,域依赖于x值的单元格。
自然地,对于数独游戏,单元格(x)邻居的列表是与x在同一列、同一行和同一3x3分区中的所有单元格的并集。虽然前两个子集可以很容易地用一个循环计算,但我不能想出一个整洁的方法来收集分区邻居,因为根据单元格在分区中的位置,有9个不同的非重叠场景。
也许将值存储在一个集合或动态列表中并在之后对其进行dedup可能是一个更好的解决方案,但我正在使用C编程语言,并希望将库的使用保留为libc。我也不需要说的数据结构在其他任何地方,所以我很犹豫,以实现它们。
下面是我的实现。
/*
* neighbours
* Auxiliary function to populate array with neighbour indices for cell (x) specified by index (idx).
* That is, populate the array with indices of the cells such that constraints on their domain depend on value of x.
* This function is only declared to increase level of abstraction and simplify coding.
* It also doesn't generalize for different board sizes as it assumes all cells have 20 neighbours.
* It is not intended to be used outside the scope of ac3, and therefore is marked auxiliary.
*
* @param idx index of the cell which neighbours are to be determined
* @param buf a pointer to integer array with at least 20 elements (20 are populated)
* @return 1 if successful, 0 otherwise
*/
int neighbours(int idx, int* buf);
int
neighbours(int idx, int* buf) {
int x, y, partition_x, partition_y, cursor;
cursor = 4;
x = idx % BOARD_WIDTH;
y = idx / BOARD_WIDTH;
partition_x = x % 3;
partition_y = y % 3;
if (partition_x == 0 && partition_y == 0) {
buf[0] = IDX(x+1, y+1);
buf[1] = IDX(x+2, y+2);
buf[2] = IDX(x+2, y+1);
buf[3] = IDX(x+1, y+2);
}
if (partition_x == 0 && partition_y == 1) {
buf[0] = IDX(x+1, y-1);
buf[1] = IDX(x+2, y+2);
buf[2] = IDX(x+2, y-1);
buf[3] = IDX(x+1, y+2);
}
if (partition_x == 0 && partition_y == 2) {
buf[0] = IDX(x+1, y-1);
buf[1] = IDX(x+2, y-2);
buf[2] = IDX(x+2, y-1);
buf[3] = IDX(x+1, y-2);
}
if (partition_x == 1 && partition_y == 0) {
buf[0] = IDX(x-1, y+1);
buf[1] = IDX(x+1, y+2);
buf[2] = IDX(x+1, y+1);
buf[3] = IDX(x-1, y+2);
}
if (partition_x == 1 && partition_y == 1) {
buf[0] = IDX(x-1, y-1);
buf[1] = IDX(x+1, y+2);
buf[2] = IDX(x+1, y-1);
buf[3] = IDX(x-1, y+2);
}
if (partition_x == 1 && partition_y == 2) {
buf[0] = IDX(x-1, y-1);
buf[1] = IDX(x+1, y-2);
buf[2] = IDX(x+1, y-1);
buf[3] = IDX(x-1, y-2);
}
if (partition_x == 2 && partition_y == 0) {
buf[0] = IDX(x-1, y+1);
buf[1] = IDX(x-2, y+2);
buf[2] = IDX(x-2, y+1);
buf[3] = IDX(x-1, y+2);
}
if (partition_x == 2 && partition_y == 1) {
buf[0] = IDX(x-1, y-1);
buf[1] = IDX(x-2, y+2);
buf[2] = IDX(x-2, y-1);
buf[3] = IDX(x-1, y+2);
}
if (partition_x == 2 && partition_y == 2) {
buf[0] = IDX(x-1, y-1);
buf[1] = IDX(x-2, y-2);
buf[2] = IDX(x-2, y-1);
buf[3] = IDX(x-1, y-2);
}
for (int nx = 0; nx < BOARD_WIDTH; nx++) {
if (nx == x)
continue;
buf[cursor] = IDX(nx, y);
cursor++;
}
for (int ny = 0; ny < BOARD_WIDTH; ny++) {
if (ny == y)
continue;
buf[cursor] = IDX(x, ny);
cursor++;
}
return 1;
}
我正在努力干净地实现这个方法,
1条答案
按热度按时间oyt4ldly1#
包含cell(y,x)的块位于
然后你可以做一对简单的嵌套循环