2011년 6월 17일 금요일

sudoku generation algorithm....

머 인터넷 뒤져 보면 무지하게 많겟지만...
실제로 찾아 봣음
Prolg로 된거... VB로 된거...
수학... 어렵더라....
막만들어 보면 행....
그렇지 사람이 쓰다가도... 지우고 다시 써야 되는 상황이 온다...

램덤으로 항상 1 ~ 9 를 생성 하는거는 좀...
어짜피 가용한 숫자가 몇개 안되는 상황에서...

그래서 짱구좀 굴린건...
칸을 체우다가 보면 앞으로 가능한 숫자는 점점 적어진다.
그걸 가능 배열이란 곳에 만들고
처음에 이 가능 배열은 1 ~ 9가...
근데 점점 적어지겟지..
이 가능한 숫자 배열에 불가능한 넘들은 100으로체워 버리고 바로 소트 시켜 버려서
가능한 숫자는 앞쪽으로
그리고 랜덤으로 생성하는건 가능한 숫자들의 개수로 해서 인덱스로 찾으면 좀더 빠를거
같아서.

그리고 오늘 옆자리 짝궁에게 들은 백..
그렇지 잘못되어서 더이상 쓸수 없는 경우는 되돌아 가야 하는데..
7*9 즉 7줄 이상 진행 햇을때는 2줄 백하면 문제가 없고
이하로 진행된경우는 그냥 1줄 백하면 된다.

해서 만든 허접 프로그램...


//
//  main.c
//  sudoku_gen
//
//  Created by sparrow on 11. 6. 16..
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include
#include
#include
#include
#include

int gArray[9][9]={0,};
int gAvail[9]={1,2,3,4,5,6,7,8,9};

int fn_qsort_intcmp( const void *a, const void *b ) 
    return( *(int *)a - *(int *)b); 

void makeAvailList(int x, int y);
int setNum(int x, int y);
int isConflict(void);

int main (int argc, const char * argv[])
{
    int cnt = 0;
    int x =0;
    int y =0;
    int res;
    
    double start,end;
    
    srand((int)time(NULL));
    start = clock();
    
    do{
        res = setNum(x, y);
        if (res)
        {
            cnt ++;
            y = (int)cnt / 9;
            x = cnt % 9;
        }
        else
        {
            if(isConflict())
            {
                //back
                if (cnt > 62)
                    cnt = (cnt - 9) - x;
                else
                    cnt = cnt - x;
                
                if (cnt < 0
                    cnt =0;
                
                y = (int)cnt /9;
                x = cnt % 9;
            }
        }
    }while(cnt < 81);
    
    end = clock();
    
    printf("time : %f\n", (double)(end - start)/CLOCKS_PER_SEC);
    for(y=0;y<9;y++)
    {
        for(x=0;x<9;x++)
        {
            printf(" %d ",gArray[x][y]);
        }
        printf("\n");
    }
    
    return 0;
}

void makeAvailList(int x, int y)
{
    int i,j;

    for(i=0;i<9;i++)
        gAvail[i]=i+1;
    
    for (i = 0; i <= x ; i ++ )
    {
        for( j = 0; j <9 ; j++)
        {
            if ( gAvail[j] == gArray[i][y] )
                gAvail[j] = 100;
        }
    }

    for (i = 0; i <= y ; i ++ )
    {
        for( j = 0; j <9 ; j++)
        {
            if ( gAvail[j] == gArray[x][i] )
                gAvail[j] = 100;
        }
    }
    
    qsort(gAvail, 9, sizeof(int), fn_qsort_intcmp );
    
}

int setNum(int x, int y)
{
    int idx;
    int num;
    int cnt;
    
    cnt = (9 - x);
    idx = rand() % cnt;
    
    makeAvailList(x, y);
    
    num = gAvail[idx];
    
    if ( num != 100)
    {
        gArray[x][y] = num;
        return 1;
    }
    else
    {
        return 0;
    }
}

int isConflict(void)
{
    int i;
    int cnt = 0;
    for( i =0; i <9; i ++)
    {
        if(gAvail[i] != 100)
            cnt ++;
    }
    
    if (cnt == 0)
        return 1;
    else
        return 0;
}


성능을 측정하는 코드도 넣어 보았다.
생각 보다 빠르다. 
내컴터가 그렇게 좋은것도 아니고 xcode4 디버그 환경인데...
빠르다..
[Switching to process 1411 thread 0x0]
time : 0.005082
 7  9  8  4  6  3  1  5  2 
 9  3  4  5  7  2  8  6  1 
 4  2  1  8  9  6  3  7  5 
 3  5  2  7  8  1  9  4  6 
 1  7  3  6  4  5  2  9  8 
 8  6  9  3  1  4  5  2  7 
 6  4  5  1  2  8  7  3  9 
 2  1  6  9  5  7  4  8  3 
 5  8  7  2  3  9  6  1  4 
Program ended with exit code: 0

허접 sudoku 앱을 만들기에는 부족하지 않을듯..




이런... 지금 다시 보니 개버그....

3x3 셀 안에서 1 ~ 9를 사용했는지를 체크하는 루틴이 없어서...
중복 숫자가 셀속에 있는 개버그...
완전 잘못 만들었다.. sudoku를 잘 모를고 만들엇네.... 

댓글 없음: