メニエスの名のもとに

プログラミング関係を中心としたぐだぐだブログ

ナンプレ(数独)問題作成プログラム その17 digging hole

作ったけど機能してない

digging_hole_recursion 関数を作ったけど、機能していない。つまり、穴を増やせていない。可能性としては、(1)バグ、(2)この関数で穴を増やせる確率が低い、たくさん生成すれば穴を増やせる場合もある、(3)対称性を捨てないといけない。ということだけれど、穴を増やせないなら再帰した意味がないなぁ。
とりあえず、digging_hole_recursion 関数

/**
 * digging hole アルゴリズムを再帰的に使い問題を作成する
 * 点対称な問題を作成する。
 * 人間的解法で解ける盤面を生成する。
 * @param array ナンプレ盤面(入出力)
 * @return 1: 作成できた
 * @return それ以外: 作成できなかった
 */
static int digging_hole_recursion(numpl_array * array, int pos,
                                  solve_info * info, int symmetric)
{
    fixed_only(array, FULL_SYMBOL);
    int r = solve(array, info);
    if (r != 1) {
        return r;
    }
    numpl_array best = *array;
    numpl_array save = *array;
    int min_fixed = ARRAY_SIZE + 1;
    int loop_size = ARRAY_SIZE;
    if (symmetric) {
        loop_size = ARRAY_SIZE / 2;
    }
    for (int i = pos; i < loop_size; i++) {
        int idx1 = i;
        int idx2 = get_counter(idx1);
        if (array->ar[idx1].fixed == 0) {
            continue;
        }
        array->ar[idx1].fixed = 0;
        array->ar[idx1].symbol = FULL_SYMBOL;
        if (symmetric) {
            array->ar[idx2].fixed = 0;
            array->ar[idx2].symbol = FULL_SYMBOL;
        }
        r = digging_hole_recursion(array, i + 1, info, symmetric);
        if (r <= 0) {
            *array = save;
            continue;
        } else if (r == 1) {
            if (info->fx_count < min_fixed) {
                min_fixed = info->fx_count;
                best = *array;
            }
            *array = save;
        }
    }
    *array = save;
    if (min_fixed == ARRAY_SIZE + 1) {
        return -1;
    } else {
        return 1;
    }
}

まあ、頑張ってもそんなには良くならないので、見切りを付けて次に進むべきだろうな。