数独をバックトラックで解く3

ちょっと納得してなかったので、、、
特に

    /* 次の座標に何の値が入るか調べる */
    int check_number;
    for(check_number = 1; check_number <= GOBAN_N;) {
        /* 再帰させる */
        if(getans(ix, iy, check_number, konkai) == 0) {
            /* 正解が見つかったとき */
            return 0;
        }
        check_number++;
    }
この辺りが。
すっきりしないというか、2カ所でforループ使いたくねぇみたいな。。。


で、修正してみた。

/* バックトラック */
int check(int ix, int iy, struct GOBAN konkai){
    int cx, cy;
    int sx, sy;
    int dupli;
    int ret;
    int number = 1;

    while (konkai.number[ix][iy] != 0) {
        /* マスに数字が入っている場合、次のマスを調べます */
        ix++;
        if(ix >= GOBAN_X) {
            ix = 0;
            iy++;
            if(iy >= GOBAN_Y) {
                /* 全てのマスが埋まった時、解答が見つかったと判断 */
                for(cy = 0; cy < GOBAN_Y;) {
                    for(cx = 0; cx < GOBAN_X;) {
                        goban.number[cx][cy] = konkai.number[cx][cy];
                        cx++;
                    }
                    cy++;
                }
                return 0;
            }
        }
    }

    /* 全ての数を試してみる */
    for(number = 1; number <= GOBAN_N;) {
//        printf("%d,%d = %d\n", ix, iy, number);
        dupli = 0;

        /* タテの列で値が入るかをチェックする */
        for (cy = 0; cy < GOBAN_Y; ++cy) {
            if(konkai.number[ix][cy] == number) {
                /* 既にチェックした数が存在した */
                dupli = 1;
            }
        }
        /* ヨコの列で値が入るかをチェックする */
        for (cx = 0; cx < GOBAN_X; ++cx) {
            if(konkai.number[cx][iy] == number) {
                /* 既にチェックした数が存在した */
                dupli = 1;
            }
        }
        /* 3*3のマスで値が入るかをチェックする */
        sx = ix - (ix % GOBAN_T);
        sy = iy - (iy % GOBAN_T);
        for(cx = 0; cx < GOBAN_T; ++cx) {
            for(cy = 0; cy < GOBAN_T; ++cy) {
                if(konkai.number[sx + cx][sy + cy] == number) {
                    /* 既にチェックした数が存在した */
                    dupli = 1;
                }
            }
        }
       
        if(dupli == 0) {
            /* 値が入る事が判ったので値を入れてみる */
            konkai.number[ix][iy] = number;
            if((ret = check(ix, iy, konkai)) == 0) {
                return 0;
            }
        }
       
        number++;
    }
    /* 1〜9までそれも答えでは無い時 */
    return -1;
}

こっちのほうが、読み飛ばし(既に値が入っていたときの処理)が複数回発生しないぶん、少し早い。

なんとなくスッキリした。。。

sudoku.tar.gz

多分、普通の環境ならmakeすれば動くと思う。