日本語の疑似コードとはどのようなものでしょうか?
例示できますか?
さて、Java は名前に日本語が使えます。例えばこんな風に、
import java.util.*; // List, ArrayList
class Cand {
/**
* 単一候補法
* @param 行列 (matrix)
* @param 候補行列 (candidate matrix)
*/
public void 単一候補法(int[][] 行列, int[][] 候補行列) {
List<Integer> 候補リスト = new ArrayList<>();
for (int i = 0; i < Utility.行; i++)
for (int j = 0; j < Utility.列; j++)
if (候補行列[i][j] > 0) { //候補の取得
候補リスト = Utility.オンビットのリスト取得(候補行列[i][j]);
if (候補リスト.size() == 1) {
//1個しか候補なかったら記憶したビットに対応する数字を確定
行列[i][j] = 候補リスト.get(0);
Utility.行と列とブロックの中の候補を排除(
候補行列,
new Point(i, j),
(int)Math.pow(2, 候補リスト.get(0))
);
}
}
}
}
class Utility {
static final int 行 = 9, 列 = 9;
static List<Integer> オンビットのリスト取得(int 候補) {
List<Integer> 候補リスト = new ArrayList<>();
for (int i = 1; i <= 9; i++)
if ((候補 >> i & 1) == 1) 候補リスト.add(i);
return 候補リスト;
}
static void 行と列とブロックの中の候補を排除(
int[][] 候補行列, Point 点, int ビット
) {
int r = 点.row, c = 点.col;
for (int i = 0; i < 9; i++) {
候補行列[r][i] &= ~ビット;
候補行列[i][c] &= ~ビット;
}
r = r / 3 * 3; c = c / 3 * 3;
for (int k = r + 3; r < k; r++) {
候補行列[r][c] &= ~ビット;
候補行列[r][c+1] &= ~ビット;
候補行列[r][c+2] &= ~ビット;
}
候補行列[点.row][点.col] |= ビット;
}
static void 候補行列表示(int[][] 候補行列) {
for (int i = 0; i < 9; i++) {
for (int k = 1; k <= 9; k += 3) {
for (int j = 0; j < 9; j++)
候補表示(候補行列[i][j], k);
System.out.println();
}
System.out.println();
}
System.out.println("--");
}
static void 候補表示(int b, int k) {
System.out.print(" ");
for (int i = 0; i < 3; i++)
System.out.print(((1<<(k+i)) & b) != 0 ? (char)('0' + k+i) : '.');
}
}
class Point {
int row, col;
Point(int i, int j) { row = i; col = j; }
}
class Test {
int[][] 行列 = {
{ 0, 8, 4, 0, 0, 0, 3, 7, 0 },
{ 6, 0, 0, 3, 0, 9, 0, 0, 2 },
{ 2, 0, 0, 0, 0, 5, 0, 0, 8 },
{ 0, 4, 9, 0, 0, 0, 0, 6, 0 },
{ 0, 0, 0, 0, 6, 0, 0, 0, 0 },
{ 0, 6, 0, 0, 0, 0, 2, 8, 0 },
{ 3, 0, 0, 4, 0, 0, 0, 0, 6 },
{ 9, 0, 0, 2, 0, 7, 0, 0, 4 },
{ 0, 5, 7, 0, 0, 0, 9, 2, 0 }
};
int[][] 候補行列 = new int[9][9];
public static void main(String[] args) { new Test(); }
Test() {
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
if (行列[i][j] == 0)
候補行列[i][j] = 0x3fe; // 2進 0011 1111 1110
else
候補行列[i][j] = 1 << 行列[i][j];
Utility.候補行列表示(候補行列);
Cand c = new Cand();
c.単一候補法(行列, 候補行列);
Utility.候補行列表示(候補行列);
c.単一候補法(行列, 候補行列);
Utility.候補行列表示(候補行列);
}
}
実行してみると、c.単一候補法(行列, 候補行列);
を繰り返すにしたがって
候補が減っていくのが分かるでしょう。
ただ、数独はこれだけでは解にたどり着けません。
なお、
List<Integer> 候補リスト = new ArrayList<>();
は
あとで代入があるから、List<Integer> 候補リスト;
でいいし、
(int)Math.pow(2, 候補リスト.get(0)
は
1 << 候補リスト.get(0)
にしたほうがいいでしょう。