问候,
几年前,世界上的很大一部分完全疯了。 不是因为
全球气候变化的原因,不是因为在
中东,也不是因为全球饥荒,而是因为一个谜:数独。
这就是Sudoku的全部意义
:
+-------+-------+-------+
| . . . | . . . | . . . |
| . . . | . . . | . . . |
| . . . | . . . | . . . |
+-------+-------+-------+
| . . . | . . . | . . . |
| . . . | . . . | . . . |
| . . . | . . . | . . . |
+-------+-------+-------+
| . . . | . . . | . . . |
| . . . | . . . | . . . |
| . . . | . . . | . . . |
+-------+-------+-------+
在点的位置,我们可以用数字记下数字1 ... 9
限制数字只能在每一行,每一列和每一行中出现一次
3x3小正方形。 听起来很容易,但仍然有数百万人
全世界发现这个小难题比灾难更为重要
如上所述。
本文为三部分,主要是因为允许的最大大小
使用此论坛软件的文章。 本文的第一部分是
通过数独求解器所需的基本功能。
我不喜欢这些类型的谜题:我必须思考很多,记下我的想法
之前做过,纠正我的错误等等。所以我决定建立一个小程序
那会为我解决问题。 我拿出我的涂鸦纸,然后这样做:
... 0 1 2 3 4 5 6 7 8
+-------+-------+-------+
0 | . . . | . . . | . . . |
1 | . 0 . | . 1 . | . 2 . |
2 | . . . | . . . | . . . |
+-------+-------+-------+
3 | . . . | . . . | . . . |
4 | . 3 . | . 4 . | . 5 . |
5 | . . . | . . . | . . . |
+-------+-------+-------+
6 | . . . | . . . | . . . |
7 | . 6 . | . 7 . | . 8 . |
8 | . . . | . . . | . . . |
+-------+-------+-------+
我只给行,列编号,然后给九个小方块一个索引
号码也。 我还决定要用数字填充每个职位
1 ... 9,但是Java更喜欢索引值0 ... 8。
给定行索引“ i”和列索引“ j”,我要检查是否
我可以在其中放置一个数字值“ val”。 对于行,我需要一个布尔值
告诉我值“ val”是否已在行“ i”中使用:
boolean[][] rows= new boolean[9][9];
...
if (row[i][val]) // 'val' is already present in row 'i'
列“ j”中的值“ val”相同:
boolean[][] columns= new boolean[9][9];
...
if (columns[j][val]) // 'val' is already present in column 'j'
然后有那些小方块...经过一番乱写之后,我注意到了
规律性并记录如下:
boolean[][] squares= new boolean[9][9];
...
if (squares[3*(i/3)+j/3][val]) // 'val' is already present in this square
当然,我需要这个小板子:
private int[][] board= new int[9][9];
到目前为止很好:我可以在需要时标记这三个二维数组
在其中放置一个值“ val”。 让我们为其编写一些代码; “ val”值必须
是0 ... 8范围内的值,但我想存储值1 ... 9;
开始:
private boolean possible(int i, int j, int val) {
// position already taken or invalid?
if (rows[i][val] || columns[j][val] ||
squares[3*(i/3)+j/3][val])
return false;
// position i,j is taken now:
rows[i][val]= true;
columns[j][val]= true;
squares[3*(i/3)+j/3][val]= true;
board[i][j]= val+1;
return true;
}
如果不能将数字“ val”放在位置,则此小方法将返回false
i,j,如果可以将其存储在其中,则返回true。
我也想从板上删除一个数字,所以我这样写:
private void reset(int i, int j) {
// adjust to the range 0 ... 8
int val= board[i][j]-1;
board[i][j]= 0;
// location i,j is free:
squares[3*(i/3)+j/3][val]= false;
columns[j][val]= false;
rows[i][val]= false;
}
大多数(如果不是全部)Sudoko拼图已经填充了几个单元格。
这是一种用数字填充单元格的便捷方法:
public boolean setValue(int i, int j, int val) {
return possible(i, j, val-1);
}
此方法假定数字在正常范围1 ... 9内并照顾
调整范围为0 ... 8.如果不能在该位置设置数字
位置由于某种原因或其他原因,该方法返回false。 如果有
没问题,该方法返回true。
这是一个在位置i,j处获取值的简单方法:
public int getValue(int i, int j) {
return board[i][j];
}
现在我们有了原始功能:我们可以正确获取并设置一个单元格
值,我们可以再次重置。 我们还不能解决数独难题
我们很方便地设置了整个电路板,甚至无法正确打印它。
读和写整个数独板将是第二个主题
本文的一部分。 到时候那里见。
亲切的问候,
乔斯