掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.28723

数独の重複チェック
投稿者---pit(2006/11/04 21:45:05)


数独という遊びがありますよね
升目に数字を埋めていき
同じ区域に同じ値が存在せず(1〜9までが各一回ずつ現れる)
行方向列方向に重複が無ければOKというアレです。
今回、同一区域内はチェックせず
行列方向のみをチェックするプログラムを作ってみたのですが
上手く動作しません。

どこがおかしいのか教えていただけないでしょうか?
お願いします

#include<stdio.h>
#include<string.h>

#define MAX_ROW 17
#define MAX_COL 8
    
char V_Check(char [][MAX_ROW] , int);
char H_Check(char [][MAX_ROW] , int);

int main(){
    
    int n;
    static char matrix[MAX_COL][MAX_ROW + 1];
    
    memset(matrix , '\0' , sizeof((MAX_ROW + 1)*(MAX_COL + 1)));
    
    /* 解答例の入力 */
    for( n = 0 ; n <= MAX_COL ; n++ ){
        scanf("%c %c %c %c %c %c %c %c %c",&matrix[n][1],&matrix[n][3],&matrix[n][5],&matrix[n][7],&matrix[n][9],&matrix[n][11],&matrix[n][13],&matrix[n][15],&matrix[n][17]);
        fflush(stdin);
    }
    
    /* 縦方向への走査 */   
    for( n = 1 ; n <= MAX_ROW ; n+=2 )
        V_Check(matrix , n);
    
    /* 横方向への走査 */   
    for( n = 0 ; n <= MAX_COL ; n++ )
        H_Check(matrix , n);
    
    for( n = 0 ; n <= MAX_COL ; n++ )   
        printf("%s\n" , matrix[n]);
    
    return 0;
    
}
    
char H_Check(char matrix[][MAX_ROW] , int y){
    
    int m,n,p,pivot;
    
    for( p = 1 ; p <= MAX_ROW ; p+=2 ){
        pivot = matrix[y][p];
        for( m = y , n = p+2 ; n <= MAX_ROW ; n += 2 ){
            if( pivot == matrix[m][n] )
                matrix[m][p - 1] = matrix[m][n - 1] = '*'; /* 同一の値が格納されいた場合'*'を入れる */
        }
    }
    
    return 0;
    
}
    

char V_Check(char matrix[][MAX_ROW] , int x){
    
    int m,n,p,pivot;
    
    for( p = 0 ; p <= MAX_ROW ; p++ ){
        pivot = matrix[p][x];
        for ( m = p+1 , n = x ; m <= MAX_COL ; m++ ){
            if(pivot == matrix[m][n])
                matrix[p][n - 1] = matrix[m][n - 1] = '*'; /* 同一の値が格納されいた場合'*'を入れる */
        }
    }
    
    return 0;
    
}


入力例
1 2 3 4 2 6 7 8 9
3 4 5 6 7 8 9 1 2
6 7 8 9 1 2 3 4 5
4 5 6 7 8 9 1 2 3
9 1 2 3 4 9 6 7 8
2 3 4 5 6 7 8 9 1
5 6 7 8 9 1 2 3 4
7 8 9 1 2 3 4 5 6
8 9 1 2 3 4 5 6 7



出力例
 1*2 3 4*2 6 7 8 9
 3 4 5 6 7 8 9 1 2
 6 7 8 9 1 2 3 4 5
 4 5 6 7 8*9 1 2 3
*9 1 2 3 4*9 6 7 8
 2 3 4 5 6 7 8 9 1
 5 6 7 8 9 1 2 3 4
 7 8 9 1*2 3 4 5 6
 8 9 1 2 3 4 5 6 7


※テストしてみたところ*9だけが一回出力されました。

また、次のような警告も出ます(矢印をつけておきました)
警告 W8075 Sudoku_Check.c 25: 問題のあるポインタの変換(関数 main )
警告 W8075 Sudoku_Check.c 29: 問題のあるポインタの変換(関数 main )





この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:数独の重複チェック 28726 kolona 2006/11/04 23:46:27
<子記事> Re:数独の重複チェック 28729 kolona 2006/11/05 00:11:12
<子記事> Re:数独の重複チェック 28742 かずま 2006/11/05 02:35:38
<子記事> Re:数独の重複チェック 28744 pit 2006/11/05 03:31:29


No.28726

Re:数独の重複チェック
投稿者---kolona(2006/11/04 23:46:27)


>数独という遊びがありますよね

>どこがおかしいのか教えていただけないでしょうか?
>お願いします
>
「数独を、空白一個ずつを含んだchar配列に格納し、重複していた数字には左に*をいれて表示したい」といった、自分の望む結果をはっきり書いてください。ほぼ明らかですが、書いてあった方が、読む側も余計な推理をせずにすみます。

問題ありそうなとこを挙げてみます。

1つめの問題
static char matrix[MAX_COL][MAX_ROW + 1];
MAX_COLは8と宣言されているので+1しないと1行まるまる足りません

2つめの問題。恐らく、一番の問題はここです
memset(matrix , '\0' , sizeof((MAX_ROW + 1)*(MAX_COL + 1)));
\0は終端文字列なので、 先頭に終端文字列が入った状態になります。
これをprintf("%s")で表示すれば当然何も表示されません。
一個だけ表示されていたのは、*を\0の上に上書きしたからでしょう。


この投稿にコメントする

削除パスワード

No.28729

Re:数独の重複チェック
投稿者---kolona(2006/11/05 00:11:12)


>また、次のような警告も出ます(矢印をつけておきました)
>警告 W8075 Sudoku_Check.c 25: 問題のあるポインタの変換(関数 main )
>警告 W8075 Sudoku_Check.c 29: 問題のあるポインタの変換(関数 main )

2次元配列を扱うにはメモリサイズを明示して関数のプロトタイプを宣言する必要があるようです
char V_Check(char [][MAX_ROW] , int);
char H_Check(char [][MAX_ROW] , int);

char V_Check(char [MAX_COL][MAX_ROW] , int);
char H_Check(char [MAX_COL][MAX_ROW] , int);

添字の値は配列の宣言と全く同じでないと、問題のあるポインタの変換です。

あと、指摘し忘れましたが、どんな場合でも環境は書いてください。


この投稿にコメントする

削除パスワード

No.28742

Re:数独の重複チェック
投稿者---かずま(2006/11/05 02:35:38)


どこがおかしいかの指摘は既にされているので、
数独を解くプログラムを書いてみました。
#include <stdio.h>
#include <stdlib.h>

char b[9][9], t;

void print(void)
{
    int r, c, i;
    for (r = 0; r < 9; ) {
        puts("+-------+-------+-------+");
        for (i = r + 3; r < i; r++) {
            for (c = 0; c < 9; c += 3)
                printf("| %c %c %c ", b[r][c], b[r][c+1], b[r][c+2]);
            puts("|");
        }
    }
    puts("+-------+-------+-------+");
}

int check(int r, int c, int n)
{
    int i;
    for (i = 0; i < 9; i++)
        if (b[r][i] == n || b[i][c] == n) return 0;
    for (c -= c % 3, r -= r % 3, i = r + 3; r < i; r++)
        if (b[r][c] == n || b[r][c+1] == n || b[r][c+2] == n) return 0;
    return 1;
}

void step(int r, int c)
{
    if (c == 9) c = 0, r++;
    if (r == 9) {
        print();
        if (++t > 1) puts("more than one solution"), exit(1);
    } else if (b[r][c] == ' ') {
        int n;
        for (n = '1'; n <= '9'; n++)
            if (check(r, c, n)) b[r][c] = n, step(r, c + 1);
        b[r][c] = ' ';
    } else 
        step(r, c + 1);
}

int main(int argc, char *argv[])
{
    FILE *fp = stdin;  int r, c;  char n;

    if (argc >= 2) fp = fopen(argv[1], "r");
    if (!fp) puts("can't open the file"), exit(1);
    for (r = 0; r < 9; r++)
        for (c = 0; c < 9; c++) {
            fscanf(fp, " %c", &n);
            b[r][c] = (n >= '1' && n <= '9') ? n : ' ';
        }
    print();
    step(0, 0);
    return 0;
}

入力例
.......74
..2.....9
.4..67...
.....31..
..6...2..
..89.....
...12..5.
8.....6..
79.......
出力例
+-------+-------+-------+
|       |       |   7 4 |
|     2 |       |     9 |
|   4   |   6 7 |       |
+-------+-------+-------+
|       |     3 | 1     |
|     6 |       | 2     |
|     8 | 9     |       |
+-------+-------+-------+
|       | 1 2   |   5   |
| 8     |       | 6     |
| 7 9   |       |       |
+-------+-------+-------+
+-------+-------+-------+
| 6 8 3 | 2 1 9 | 5 7 4 |
| 1 7 2 | 4 8 5 | 3 6 9 |
| 5 4 9 | 3 6 7 | 8 2 1 |
+-------+-------+-------+
| 2 5 7 | 6 4 3 | 1 9 8 |
| 9 3 6 | 8 7 1 | 2 4 5 |
| 4 1 8 | 9 5 2 | 7 3 6 |
+-------+-------+-------+
| 3 6 4 | 1 2 8 | 9 5 7 |
| 8 2 5 | 7 9 4 | 6 1 3 |
| 7 9 1 | 5 3 6 | 4 8 2 |
+-------+-------+-------+



この投稿にコメントする

削除パスワード

No.28744

Re:数独の重複チェック
投稿者---pit(2006/11/05 03:31:29)


みなさんありがとうございます
参考になります

かずまさん、すごいですね( ;∀;)
こんなプログラムを直ぐ組めちゃうなんて・・・・
自分もいつかこうなりたいです!


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧