Sudoku Programmers Forum Index

 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister   ProfileProfile   Log inLog in          Games  Calendar

Log in to check your private messagesLog in to check your private messages   

Bit Based Sudoku Solver (BB_Sudoku) V0.5
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9  Next
 
Post new topic   Reply to topic    Sudoku Programmers Forum Index -> Programming sudoku
View previous topic :: View next topic  
Author Message
serbo

Joined: 22 Dec 2008
Posts: 6
:

Items
PostPosted: Fri Dec 26, 2008 11:03 pm    Post subject: Reply with quote

zerothbase wrote:
Generating random solved grids is a very fast operation compared to the rest of the steps involved.

see 2nd post on this topic in the setting sudoku forum

You can simply iterate over the squares in order (1 to 81) and set a random value of the possible for each square. If you run into a square with no possibilities, backtrack.

This is very fast.

--Zerothbase

Later I found your post with code for generator in another thread. I was using code that I was thinking is good. Now after filling needed code to make your function work I do not think that any more. Your function with JasonLion's suggested datastructure I think I got really fast generator for filled grid. It is more than 50 times faster than my original code (also coded in C). On my slow PC it previously needed more than 5 minutes to generate 100000 filled grids. With your function it now need little more than 7 sec.

My main reason for previous question was fact that when I was generating puzzle most time was spent while generating solution grid. That will change now I hope.

Here is your function completed to full program:

Code:

#include <stdio>
#include <stdlib>
#include <time>

#define SIZE 9
#define GRID (SIZE*SIZE)

static int Bit2Value[512];

static int const BitCount[512] = {
        0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
        1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
        2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
        3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
        4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,5,6,6,7,6,7,7,8,6,7,7,8,7,8,8,9};


static int const which_row[GRID] = {
        0,  0,  0,  0,  0,  0,  0,  0,  0,
        1,  1,  1,  1,  1,  1,  1,  1,  1,
        2,  2,  2,  2,  2,  2,  2,  2,  2,
        3,  3,  3,  3,  3,  3,  3,  3,  3,
        4,  4,  4,  4,  4,  4,  4,  4,  4,
        5,  5,  5,  5,  5,  5,  5,  5,  5,
        6,  6,  6,  6,  6,  6,  6,  6,  6,
        7,  7,  7,  7,  7,  7,  7,  7,  7,
        8,  8,  8,  8,  8,  8,  8,  8,  8
};
static int const which_col[GRID] = {
        0,  1,  2,  3,  4,  5,  6,  7,  8,
        0,  1,  2,  3,  4,  5,  6,  7,  8,
        0,  1,  2,  3,  4,  5,  6,  7,  8,
        0,  1,  2,  3,  4,  5,  6,  7,  8,
        0,  1,  2,  3,  4,  5,  6,  7,  8,
        0,  1,  2,  3,  4,  5,  6,  7,  8,
        0,  1,  2,  3,  4,  5,  6,  7,  8,
        0,  1,  2,  3,  4,  5,  6,  7,  8,
        0,  1,  2,  3,  4,  5,  6,  7,  8
};
static int const which_box[GRID] = {
        0,  0,  0,  1,  1,  1,  2,  2,  2,
        0,  0,  0,  1,  1,  1,  2,  2,  2,
        0,  0,  0,  1,  1,  1,  2,  2,  2,
        3,  3,  3,  4,  4,  4,  5,  5,  5,
        3,  3,  3,  4,  4,  4,  5,  5,  5,
        3,  3,  3,  4,  4,  4,  5,  5,  5,
        6,  6,  6,  7,  7,  7,  8,  8,  8,
        6,  6,  6,  7,  7,  7,  8,  8,  8,
        6,  6,  6,  7,  7,  7,  8,  8,  8
};

int row[SIZE];
int col[SIZE];
int box[SIZE];
int solution[GRID];

#define GET_POSSIBLE(k) (row[which_row[k]] & col[which_col[k]] & box[which_box[k]])
#define BITCOUNT(mask) (BitCount[mask])

inline
void set(int k, int try)
{
        row[which_row[k]] &= ~try;
        col[which_col[k]] &= ~try;
        box[which_box[k]] &= ~try;
        solution[k] = try;
}

inline
void clear(int k, int try)
{
        row[which_row[k]] |= try;
        col[which_col[k]] |= try;
        box[which_box[k]] |= try;
}

void init()
{
        int j;
        for(j = 0; j < SIZE; j++) {
                row[j]= 511;
                col[j]= (1 << SIZE) - 1; /* different look of same value */
                box[j]= 0777;            /* different look of same value */
        }
}

int backTrackGen(int k)
{
        if(k == GRID)
                return 1;
        int possib = GET_POSSIBLE(k);
        while(possib)
        {
                int count = BITCOUNT(possib);
                int try = possib;
                int clearCnt = rand() % count;
                int j;
                for(j = 0; j < clearCnt; j++)
                        try &= ~(try & -try);
                try &= -try;
                set(k, try);
                if (backTrackGen(k+1))
                        return 1;
                clear(k, try);
                possib &= ~try;
        }
        return 0;
}


void display_solution ()
{
        int i;
        for (i = 0; i < GRID; i++) {
                int value;
                value = Bit2Value[solution[i]];
                if (value)
                        printf ("%c", value+'0');
                else
                        printf (".");
        }
        printf ("\n");
}

static int num  = 100000;

int main(int argc, char* argv[])
{
        int i;
        srand(time(0));
        if (argc == 2)
                num = atoi(argv[1]);
        for (i = 0; i < SIZE; i++)
                Bit2Value[1 << i] = i+1;

        for (i=0; i<num; i++) {
                init();
                backTrackGen(0);
                display_solution();
        }
        return 0;
}


How does this compare with your current implementation?

As it turn out there is always to something learn. I learned that data structure used has very big impact, memory management too (I used to call malloc, free and memmove almost 10 times for every recursion needed) even when using same algorithm. (Basic lesson Wirth would say) Smile
Back to top
View user's profile Send private message
briturner

Joined: 14 Oct 2008
Posts: 75
:

Items
PostPosted: Wed Dec 31, 2008 9:25 pm    Post subject: Reply with quote

sorry, posted twice when I got a script error when posting

Last edited by briturner on Wed Dec 31, 2008 9:49 pm; edited 1 time in total
Back to top
View user's profile Send private message
briturner

Joined: 14 Oct 2008
Posts: 75
:

Items
PostPosted: Wed Dec 31, 2008 9:45 pm    Post subject: Reply with quote

Greetings again,

I have been away for awhile, but I have been reading the forum and making a few small changes to my solver.

I implemented 2 new solving methodologies, the first being a generic fishy searcher. X-Wing, Swordfish, and Jellyfish methods are all really just a variation of searching for subsets, and as such can be done with a similar generic routine.

After implementing that, it still only solved 75 of the top 50000 without guessing. I looked at a number of other solving techniques, but they mostly fell within 2 generic methods:
- If we assume X = a, and this leads to X cannot = a, then X != a
- If we assume each possibility of X, and all the possibilities lead to Y cannot = a, then Y != a

XY-Wing, XYZ-Wing, Connected pairs, Finned fish and others all fit in this category. So, I implemented a methodology that tries 1 step for each possibility, and searches for common eliminations. In my code, I called this "1-Step Commonality". This is different than guessing and backtracking in that we are only testing the changes in a single cell, and only 1 level. This was much easier than making specific routines each method.

With these 2 methods added, all the top 50000 can be solved without guessing, as can the top 1465. I am currently down to 551 puzzles that require guessing out of some 100,000+ puzzles.

Here are a couple puzzles that I still need to use guessing and backtracking:
3.......1.2...6.9...5...8...7.2.4......867........9.4...8...5...6.9...2.1.......3
.....1.8..3.5..2......4...62..3..5.......8.1.....6...4.5....7..3..97.....62......
.6.9....35....4.2.....8.4..8......5...3...7...9......1..1.5.....7.3....99....2.4.
.....1.2.3...4.5.....6....7..1.....6.4..8..9.5.....3..8....2....5..9.4....67.....
4.......3.1...2.7...8...5...6.2.9......1........68..9...5...8...2.7...1.3.......4


For those really interested, here are the code snippets for the 2 solving routines (only for those really really interested, since it is not commented):
Code:
 
inline void FindFishies (void)
{ int b, i, g, p, m, t[10], v[10], grid[10], x, y;

  for (b = 1; b <= 9; b++)
  { if (Changed) break;
    for (g = 0; g < 9; g++) grid[g] = 0;
    for (g = 0; g < 9; g ++)
      for (i = 0; i < 9; i++)
       if (G[PIdx].Grid[(g*9)+i] & V2B[b]) grid[g] |= V2B[i+1];
   
    for (g = m = 0; g < 9; g++)
      if (grid[g]) m++;
    if (m <2> 0)
    { t[p]++;
      if (t[p] == 9) { p--; continue; }
      if (p == 1)
      { v[1] = grid[t[p]];
        if ((!v[1]) || (NSet[v[1]] > m)) continue;
        p++; t[2] = t[1]; continue;
      }
      if (!grid[t[p]]) continue;
      v[p] = v[p-1] | grid[t[p]];
      if (NSet[v[p]] > m) continue;
      if (NSet[v[p]] == p)
      { for (i = 0; i < 9; i++)
        if (grid[i] & ~v[p])
        { x = grid[i] & v[p];
          while (x)
         { y = (i*9) + B2V[x & -x] - 1;
              if (G[PIdx].Grid[y] & V2B[b])
           { G[PIdx].Grid[y] ^= V2B[b];
                if (B2V[G[PIdx].Grid[y]])
                  PushSingle(y, G[PIdx].Grid[y]);
                MarkChanged(y);
              }
           x ^= (x & -x);
         }
          }
        p = 1;
        continue;
      }
      if (p < m) { p++; t[p] = t[p-1]; }
    }
  }
}



inline void DoOneStep (int use_methods)
{ int i, j, x1, x2, x3, mt, testcell, tested[81], testpidx;

  for (i = 0; i < 81; i++) tested[i] = 0;
  testpidx = PIdx;

  while (!Changed)
  { // Find next spot to check
    testcell = mt = x3 = 99;
    for (i = 0; i < 81; i++)
      if ((NSet[G[PIdx].Grid[i]] <mt> 1) && !tested[i])
      { x1 = NSet[G[PIdx].Grp[C2Grp[i][0]]] + NSet[G[PIdx].Grp[C2Grp[i][1]]] + NSet[G[PIdx].Grp[C2Grp[i][2]]];
        if ((NSet[G[PIdx].Grid[i]] < mt) ||
          ((NSet[G[PIdx].Grid[i]] == mt) && (x1 <= x2) && (OneStepP[i] <= x3)))
        { x2 = x1;
          testcell = i;
          mt = NSet[G[PIdx].Grid[i]];
        x3 = OneStepP[i];
        }
      }
 
    if (testcell == 99) return;
    tested[testcell] = 1;
   OneStepI++; OneStepP[testcell] = OneStepI;

    for (j = 0; j < NSet[G[PIdx].Grid[testcell]]; j++)
   {
      G[PIdx+1+j] = G[PIdx];
      PushSingle(testcell, NSetX[G[PIdx].Grid[testcell]][j]);
     PIdx = testpidx + 1 + j; 
     Solver(1, use_methods & ~(USE_GUESSES | USE_1_STEP), 0, PIdx, NULL);
      PIdx = testpidx;
      if (No_Sol) 
        for (i = 0; i < 81; i++) G[PIdx+1+j].Grid[i] = 0;
     else
        for (i = 0; i < 81; i++)
         if (!G[PIdx+1+j].Grid[i]) G[PIdx+1+j].Grid[i] = SolGrid[i];
     No_Sol = 0; SingleCnt = 0;
   }
    for (j = 1; j < NSet[G[PIdx].Grid[testcell]]; j++)
      for (i = 0; i < 81; i++) G[PIdx+1].Grid[i] |= G[PIdx+1+j].Grid[i];
    for (i = 0; i < 27; i++) ChangedGroup[i] = 0; Changed = 0;
    for (i = 0; i < 81; i++)
     if (G[PIdx].Grid[i] && (G[PIdx].Grid[i] != G[PIdx+1].Grid[i]))
     { G[PIdx].Grid[i] = G[PIdx+1].Grid[i];
       if (B2V[G[PIdx].Grid[i]]) PushSingle(i, G[PIdx].Grid[i]);
        MarkChanged(i);
      }
  }
}


I will release the new code once I fix a problem in my generator that causes it to crash after a few hours (painful to find since it normally has no problems).

brit
Back to top
View user's profile Send private message
JasonLion

Joined: 16 Nov 2008
Posts: 62
:
Location: Silver Spring, MD

Items
PostPosted: Sun Jan 04, 2009 2:57 pm    Post subject: Reply with quote

briturner, from your brief description, your new solving technique sounds like it might be the same as Bowman's Bingo, or at least very similar.
Back to top
View user's profile Send private message
briturner

Joined: 14 Oct 2008
Posts: 75
:

Items
PostPosted: Sun Jan 04, 2009 5:50 pm    Post subject: Reply with quote

Greetings.

My methods I used are all very generic, rather than specific solving methods. This makes programming much easier, but rating almost impossible. I only implemented 7 methods:

- Naked Singles
- Hidden Singles (these two are also used to determine if the puzzle is solved)
- Locked Candidates
- Disjoint Subsets (which include Naked/Hidden Pairs/Triples/Quads)
- Fishies (including X-Wing, Swordfish, and Jellyfish)
- 1-Step Commonality (includes many methods) and 2-Step Commonality
- Brute Force

Since the routines are all rather generic, a Naked Pair and Hidden Quad are calculated using the same routine, same with X-Wing and Jellyfish. Since my Fishy routine is based on the Subsets, it should theoretically detect Jellyfish with up to 7 legs (I do not know if that is possibly).

I looked up Bowman's Bingo, and from what I understand, it is looking for contradictions. My method will find both contradictions, and any common information that is true when all possibilities of a cell are tested. This is similar to XY-Wing, XYZ-Wing, and finned fish.

I was originally going to write a separate routine for the XY-Wing and XYZ-Wing, but it worked out to be easier to test everything.

4 notes on my 1-Step Commonality and 2-Step Commonality:
- It is a computer method, and not something that could be easily implemented by hand, similar to brute force
- I do not claim it is anything unique, but more of a generalization of other techniques. Like Subset Counting is more of a generalization of certain techniques.
- While I gave it a name, it was only because I did not know of any existing names that would cover what I implemented.
- Brute force is still the fastest method, I only implemented more methods so I could use them for rating in my generator and for my own personal curiosity.

My rater is really terrible, but I can categorize puzzles into 4 difficulty levels using these methods:

Easy : Solved using Naked/Hidden Singles and Locked Candidates Only
Medium : Adds Disjoint Subsets and Fishies
Hard : Requires using 1-Step Commonality
Insane : Requires using 2-Step Commonality

I have not found any puzzle that needs more than the 2-Step commonality to be solved.

I currently know of 549 puzzles that are insane. Using other raters they rank between 90375 and 97529 using gsf's rater, 256,179 and 3639,2371 using sueratt, and 9.9 and 11.9 suing SE (of the 30+ I rated so far, since some literally take hours to rate). I am working on generating more insane puzzles and am now on my 3rd generator method.

brit
Back to top
View user's profile Send private message
garthd

Joined: 29 Apr 2006
Posts: 32
:

Items
PostPosted: Mon Jan 12, 2009 10:39 am    Post subject: 1-Step Commonality Reply with quote

The technique of 1-Step Commonality sounds interesting...do you have a puzzle (say from top1465) where you can post the puzzle right before the 1-Step Commonality is applied and detail how the method moves forward. Am I right in saying that for a cell with candidate 1,3 and 7 remaining, you try placing each possible candidate as the solution for the cell, and then search for any common eliminations?
Back to top
View user's profile Send private message
garthd

Joined: 29 Apr 2006
Posts: 32
:

Items
PostPosted: Mon Jan 12, 2009 10:40 am    Post subject: 1-Step Commonality Reply with quote

The technique of 1-Step Commonality sounds interesting...do you have a puzzle (say from top1465) where you can post the puzzle right before the 1-Step Commonality is applied and detail how the method moves forward. Am I right in saying that for a cell with candidate 1,3 and 7 remaining, you try placing each possible candidate as the solution for the cell, and then search for any common eliminations?
Back to top
View user's profile Send private message
garthd

Joined: 29 Apr 2006
Posts: 32
:

Items
PostPosted: Mon Jan 12, 2009 10:41 am    Post subject: 1-Step Commonality Reply with quote

The technique of 1-Step Commonality sounds interesting...do you have a puzzle (say from top1465) where you can post the puzzle right before the 1-Step Commonality is applied and detail how the method moves forward. Am I right in saying that for a cell with candidate 1,3 and 7 remaining, you try placing each possible candidate as the solution for the cell, and then search for any common eliminations?
Back to top
View user's profile Send private message
garthd

Joined: 29 Apr 2006
Posts: 32
:

Items
PostPosted: Mon Jan 12, 2009 10:42 am    Post subject: 1-step commonality Reply with quote

The technique of 1-Step Commonality sounds interesting...do you have a puzzle (say from top1465) where you can post the puzzle right before the 1-Step Commonality is applied and detail how the method moves forward. Am I right in saying that for a cell with candidate 1,3 and 7 remaining, you try placing each possible candidate as the solution for the cell, and then search for any common eliminations?
Back to top
View user's profile Send private message
briturner

Joined: 14 Oct 2008
Posts: 75
:

Items
PostPosted: Tue Jan 13, 2009 5:16 am    Post subject: Reply with quote

Greetings,

here is an example from the first puzzle of the Top_1465:
4...3.......6..8..........1....5..9..8....6...7.2........1.27..5.3....4.9........

After applying simpler techniques (hidden/naked singles, locked candidates, disjoint subsets, fishies), I ended up with this:

Code:
=== 4 === 9--65---- -8-6---21|987-5---- === 3 === 987-5---1|9---5--2- --765--2- 9-765--2-
--7---321 9---5-3-- -------21|=== 6 === --7----21 9-7-54--1|=== 8 === --7-5-32- 9-7-5432-
-876--32- 9--65-3-- -8-6---2-|987-54--- -87----2- 987-54---|9---5432- --765-32- === 1 ===

---6--321 ---6-43-- ---6-4-21|-87---3-- === 5 === -876--3-1|------32- === 9 === -87---32-
------321 === 8 === 9---5----|9-7--43-- --7-----1 9-7--43-1|=== 6 === --7-5-321 --7-5432-
---6--3-1 === 7 === 9---5----|=== 2 === -8-6----1 98-6-43-1|----543-- -8--5-3-1 -8--543--

-8-6----- ---6-4--- -8-6-4---|=== 1 === === 9 === === 2 ===|=== 7 === ----5-3-- ----5-3--
=== 5 === -------21 === 3 ===|-87------ -876----- -876-----|9------21 === 4 === 9------2-
=== 9 === -------21 === 7 ===|----5-3-- === 4 === ----5-3--|-------21 -8-6----- -8-6-----


My program picked cell 80 (row 9, Col 8), which can either be a 6 or an 8. We will try both values in that cell, but in this case, it turns out that the value of 6 resulted in an invalid grid, so we knew that the value of 8 is the correct value for the cell. Actually, all the 1-Step tests in this puzzle result in one invalid grid, so the other must be true. lets try another puzzle.

Lets try this:
7.8...3.....2.1...5.........4.....263...8.......1...9..9.6....4....7.5...........

picking it up partway through the solving:
Code:
=== 7 === ---6---21 === 8 ===|9---54--- ---654--- 9--654---|=== 3 === ---654--1 ----5--21
=== 9 === ---6--3-- ---6-4---|=== 2 === ---6543-- === 1 ===|--76-4--- -87654--- -87-5----
=== 5 === ---6--321 ---6-4-2-|-87------ ---6-43-- -87------|9--6-4-21 ---6-4--1 9------21

-8------1 === 4 === --7-5---1|--7-5-3-- === 9 === --7-5-3--|-87------ === 2 === === 6 ===
=== 3 === ---6---2- === 9 ===|--7--4--- === 8 === ---6---2-|--7--4--1 --7-54--1 --7-5---1
-8-6---2- --7-5---- --765--2-|=== 1 === ---654-2- --7654-2-|-87--4--- === 9 === === 3 ===

-------21 === 9 === --7-5-321|=== 6 === ----5--21 -8--5-32-|--7----21 -87---3-1 === 4 ===
---6-4-21 === 8 === ---6--321|9----43-- === 7 === 9----432-|=== 5 === ---6--3-1 9------21
---6-4-21 --7-5---- --765-321|98--543-- ----54-21 98--5432-|9-76---21 -876--3-1 987----21


Applying the test to cell 41 (Row 5, Col 6), it can be either a 2 or a 6. here are the grids at each possibility:

Code:
When set to 2:
=== 7 === === 2 === === 8 ===|=== 9 === === 4 === === 6 ===|=== 3 === ----5---1 ----5---1
=== 9 === === 3 === === 4 ===|=== 2 === === 5 === === 1 ===|=== 6 === -87------ -87------
=== 5 === === 1 === === 6 ===|-87------ === 3 === -87------|=== 2 === === 4 === === 9 ===

=== 1 === === 4 === --7-5----|--7-5---- === 9 === === 3 ===|=== 8 === === 2 === === 6 ===
=== 3 === === 6 === === 9 ===|=== 4 === === 8 === === 2 ===|=== 1 === --7-5---- --7-5----
=== 8 === --7-5---- === 2 ===|=== 1 === === 6 === --7-5----|=== 4 === === 9 === === 3 ===

=== 2 === === 9 === ----5-3--|=== 6 === === 1 === -8--5----|=== 7 === -8----3-- === 4 ===
=== 4 === === 8 === === 1 ===|=== 3 === === 7 === === 9 ===|=== 5 === === 6 === === 2 ===
=== 6 === --7-5---- --7-5-3--|-8--5---- === 2 === === 4 ===|=== 9 === -8----3-1 -8------1


Code:
When set to 6:
=== 7 === ---6----1 === 8 ===|9---54--- ---654--- 9---54---|=== 3 === ---654--1 === 2 ===
=== 9 === ---6--3-- === 4 ===|=== 2 === ---65-3-- === 1 ===|--76----- -8765---- -87-5----
=== 5 === ---6--3-1 === 2 ===|-87------ ---6-43-- -87------|9--6-4--1 ---6-4--1 9-------1

-8------1 === 4 === --7-5---1|--7-5-3-- === 9 === --7-5-3--|-87------ === 2 === === 6 ===
=== 3 === === 2 === === 9 ===|--7--4--- === 8 === === 6 ===|--7--4--1 --7-54--1 --7-5----
-8-6----- --7-5---- --765----|=== 1 === ----54-2- --7-54-2-|-87--4--- === 9 === === 3 ===

-------21 === 9 === --7-5-3-1|=== 6 === ----5--21 -8--5-32-|--7----21 -87---3-1 === 4 ===
---6-4-21 === 8 === ---6--3-1|9----43-- === 7 === 9----432-|=== 5 === ---6--3-1 9-------1
---6-4-21 --7-5---- --765-3-1|98--543-- ----54-21 98--5432-|9-76---21 -876--3-1 -87------



What we are looking for is any possibility that was still possible before the test, but is not possible in both the test cases. I believe there are 15 cases of this in this case, for example: in Row 2, Col 3, the value is 4 in both cases. And Row 3, Col 2 does not have the possibility of 2 in either case, either it is a 1, or the possibilities of 631. Either way, 2 can not be in that cell. After applying all 15, we end up with the following grid:

Code:

=== 7 === ---6---21 === 8 ===|9---54--- ---654--- 9--654---|=== 3 === ---654--1 ----5--21
=== 9 === ---6--3-- -----4---|=== 2 === ---65-3-- === 1 ===|--76----- -8765---- -87-5----
=== 5 === ---6--3-1 ---6---2-|-87------ ---6-43-- -87------|9--6-4-21 ---6-4--1 9-------1

-8------1 === 4 === --7-5---1|--7-5-3-- === 9 === --7-5-3--|-87------ === 2 === === 6 ===
=== 3 === ---6---2- === 9 ===|--7--4--- === 8 === ---6---2-|--7--4--1 --7-54--1 --7-5----
-8-6----- --7-5---- --765--2-|=== 1 === ---654-2- --7-54-2-|-87--4--- === 9 === === 3 ===

-------21 === 9 === --7-5-3-1|=== 6 === ----5--21 -8--5-32-|--7----21 -87---3-1 === 4 ===
---6-4-21 === 8 === ---6--3-1|9----43-- === 7 === 9----432-|=== 5 === ---6--3-1 9------21
---6-4-21 --7-5---- --765-3-1|98--543-- ----54-21 98--5432-|9-76---21 -876--3-1 -87-----1


Using this method, most puzzles can be solved, including all the Top50000 and Top1465. I do have generated some 2000+ puzzles that can not be solved using these methods, and require a 2-Step Commonality to solve.

Hope that helps some.

brit
Back to top
View user's profile Send private message
zhouyundong

Joined: 22 Nov 2008
Posts: 43
:

Items
PostPosted: Sun Jan 18, 2009 1:06 pm    Post subject: Reply with quote

http://www.killersudokuonline.com/play.html?puzzle=GW471uzq1010
GT142,My solver can solute GT(Great Than,What I called Sopare, sodoku compare), and my solver tells There are 13 ">,<s>'s, the answer is still only one.
I think what i did is good work.Can somebody translate my poor english to standard English,and publish here,thanks.
Back to top
View user's profile Send private message Send e-mail
briturner

Joined: 14 Oct 2008
Posts: 75
:

Items
PostPosted: Mon Jan 19, 2009 3:11 am    Post subject: Reply with quote

Greetings, and congratulations zhouyundong. I went ahead and the GT, LT feature into my solver today.

Not quite perfect. It misses one logical elimination. if we have X > Y < Z, it eliminates 1 from X and Z, and eliminates 9 from Y. Y actually can not be a 9 or an 8 since there are 2 number greater than Y, but my routine does not catch that yet. It still solves the puzzle correctly, because that will be caught later on, but it could cause an extra guess.

Since it is part of my main solver, it can solve puzzles with combinations of givens (normal Sudoku) and "<" ">".

my problem is that I hardcoded a single puzzle into my solver to test. Is there a site with a collection of these that can be used for testing? Assuming there is, what is the format?

thanks,
brit
Back to top
View user's profile Send private message
zhouyundong

Joined: 22 Nov 2008
Posts: 43
:

Items
PostPosted: Mon Jan 19, 2009 3:13 pm    Post subject: Reply with quote

I did some work to the format,here is my string:
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110010001000201200011000100000010101201100000002100020011000000101000000000020120210000020000000000012000000000000210000000000000001010012000201
The first 81 numbers mean that known numbers.
Then the 81*2 numbers mean that Killer's sum.
Then the 81*2 numbers mean that Killer's head index.
Then the 72*2 numbers mean that GT.(0:nothing,1:>,2:<)
Back to top
View user's profile Send private message Send e-mail
zhouyundong

Joined: 22 Nov 2008
Posts: 43
:

Items
PostPosted: Mon Jan 19, 2009 3:31 pm    Post subject: Reply with quote

Greetings All, congratulations Briturner.
I am happy to know that you are GT writer.
My solver can solve the most diffucult GT within 3 seconds,general question can be solved within 100 miliseconds.But some easy question,it can NOT solve........It can generate GT ,tonight I will generate some questions.
Do you have a good way to Connent with each other, what about ICQ?
I will send you my test cases which produced by my solver,every kind of GT cases, no answer, 1 answer 2 answers; ><5><11numbers><&2numbers...every kind.
I will send you my solver, and I am very glad to test speed with your sover,we use very different kernels. Very Happy Very Happy Very Happy
What I do next is to solve Killer.
Back to top
View user's profile Send private message Send e-mail
zhouyundong

Joined: 22 Nov 2008
Posts: 43
:

Items
PostPosted: Tue Jan 20, 2009 2:53 pm    Post subject: Reply with quote

I got The First GT questions abstract automatically produced by computer within 5 minutes.
Jan. 20 2009 22:50
It is a mile stone in the GT area,I think.
000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010200200011000200001000211200001200120010000200200001001222000012001011100202200010000000000000011000000120002120002012000102010000010000002002
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    Sudoku Programmers Forum Index -> Programming sudoku All times are GMT
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9  Next
Page 5 of 9

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Sudoku Programmers topic RSS feed 


Powered by phpBB © 2001, 2005 phpBB Group

Igloo Theme Version 1.0 :: Created By: Andrew Charron