#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned short ushort;
#define BASE 9
static const unsigned char BitsSetTable256[] =
{
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
};
static const char LogTable256[] =
{
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
};
static const char group_to_cell[3][BASE][BASE] =
{
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8 },
{ 9, 10, 11, 12, 13, 14, 15, 16, 17 },
{ 18, 19, 20, 21, 22, 23, 24, 25, 26 },
{ 27, 28, 29, 30, 31, 32, 33, 34, 35 },
{ 36, 37, 38, 39, 40, 41, 42, 43, 44 },
{ 45, 46, 47, 48, 49, 50, 51, 52, 53 },
{ 54, 55, 56, 57, 58, 59, 60, 61, 62 },
{ 63, 64, 65, 66, 67, 68, 69, 70, 71 },
{ 72, 73, 74, 75, 76, 77, 78, 79, 80 }
},
{
{ 0, 9, 18, 27, 36, 45, 54, 63, 72 },
{ 1, 10, 19, 28, 37, 46, 55, 64, 73 },
{ 2, 11, 20, 29, 38, 47, 56, 65, 74 },
{ 3, 12, 21, 30, 39, 48, 57, 66, 75 },
{ 4, 13, 22, 31, 40, 49, 58, 67, 76 },
{ 5, 14, 23, 32, 41, 50, 59, 68, 77 },
{ 6, 15, 24, 33, 42, 51, 60, 69, 78 },
{ 7, 16, 25, 34, 43, 52, 61, 70, 79 },
{ 8, 17, 26, 35, 44, 53, 62, 71, 80 }
},
{
{ 0, 1, 2, 9, 10, 11, 18, 19, 20 },
{ 3, 4, 5, 12, 13, 14, 21, 22, 23 },
{ 6, 7, 8, 15, 16, 17, 24, 25, 26 },
{ 27, 28, 29, 36, 37, 38, 45, 46, 47 },
{ 30, 31, 32, 39, 40, 41, 48, 49, 50 },
{ 33, 34, 35, 42, 43, 44, 51, 52, 53 },
{ 54, 55, 56, 63, 64, 65, 72, 73, 74 },
{ 57, 58, 59, 66, 67, 68, 75, 76, 77 },
{ 60, 61, 62, 69, 70, 71, 78, 79, 80 }
},
-
};
static const char cell_to_group[BASE*BASE][3][2] =
{
{{ 0, 0 }, { 0, 0 }, { 0, 0 }},
{{ 0, 1 }, { 1, 0 }, { 0, 1 }},
{{ 0, 2 }, { 2, 0 }, { 0, 2 }},
{{ 0, 3 }, { 3, 0 }, { 1, 0 }},
{{ 0, 4 }, { 4, 0 }, { 1, 1 }},
{{ 0, 5 }, { 5, 0 }, { 1, 2 }},
{{ 0, 6 }, { 6, 0 }, { 2, 0 }},
{{ 0, 7 }, { 7, 0 }, { 2, 1 }},
{{ 0, 8 }, { 8, 0 }, { 2, 2 }},
{{ 1, 0 }, { 0, 1 }, { 0, 3 }},
{{ 1, 1 }, { 1, 1 }, { 0, 4 }},
{{ 1, 2 }, { 2, 1 }, { 0, 5 }},
{{ 1, 3 }, { 3, 1 }, { 1, 3 }},
{{ 1, 4 }, { 4, 1 }, { 1, 4 }},
{{ 1, 5 }, { 5, 1 }, { 1, 5 }},
{{ 1, 6 }, { 6, 1 }, { 2, 3 }},
{{ 1, 7 }, { 7, 1 }, { 2, 4 }},
{{ 1, 8 }, { 8, 1 }, { 2, 5 }},
{{ 2, 0 }, { 0, 2 }, { 0, 6 }},
{{ 2, 1 }, { 1, 2 }, { 0, 7 }},
{{ 2, 2 }, { 2, 2 }, { 0, 8 }},
{{ 2, 3 }, { 3, 2 }, { 1, 6 }},
{{ 2, 4 }, { 4, 2 }, { 1, 7 }},
{{ 2, 5 }, { 5, 2 }, { 1, 8 }},
{{ 2, 6 }, { 6, 2 }, { 2, 6 }},
{{ 2, 7 }, { 7, 2 }, { 2, 7 }},
{{ 2, 8 }, { 8, 2 }, { 2, 8 }},
{{ 3, 0 }, { 0, 3 }, { 3, 0 }},
{{ 3, 1 }, { 1, 3 }, { 3, 1 }},
{{ 3, 2 }, { 2, 3 }, { 3, 2 }},
{{ 3, 3 }, { 3, 3 }, { 4, 0 }},
{{ 3, 4 }, { 4, 3 }, { 4, 1 }},
{{ 3, 5 }, { 5, 3 }, { 4, 2 }},
{{ 3, 6 }, { 6, 3 }, { 5, 0 }},
{{ 3, 7 }, { 7, 3 }, { 5, 1 }},
{{ 3, 8 }, { 8, 3 }, { 5, 2 }},
{{ 4, 0 }, { 0, 4 }, { 3, 3 }},
{{ 4, 1 }, { 1, 4 }, { 3, 4 }},
{{ 4, 2 }, { 2, 4 }, { 3, 5 }},
{{ 4, 3 }, { 3, 4 }, { 4, 3 }},
{{ 4, 4 }, { 4, 4 }, { 4, 4 }},
{{ 4, 5 }, { 5, 4 }, { 4, 5 }},
{{ 4, 6 }, { 6, 4 }, { 5, 3 }},
{{ 4, 7 }, { 7, 4 }, { 5, 4 }},
{{ 4, 8 }, { 8, 4 }, { 5, 5 }},
{{ 5, 0 }, { 0, 5 }, { 3, 6 }},
{{ 5, 1 }, { 1, 5 }, { 3, 7 }},
{{ 5, 2 }, { 2, 5 }, { 3, 8 }},
{{ 5, 3 }, { 3, 5 }, { 4, 6 }},
{{ 5, 4 }, { 4, 5 }, { 4, 7 }},
{{ 5, 5 }, { 5, 5 }, { 4, 8 }},
{{ 5, 6 }, { 6, 5 }, { 5, 6 }},
{{ 5, 7 }, { 7, 5 }, { 5, 7 }},
{{ 5, 8 }, { 8, 5 }, { 5, 8 }},
{{ 6, 0 }, { 0, 6 }, { 6, 0 }},
{{ 6, 1 }, { 1, 6 }, { 6, 1 }},
{{ 6, 2 }, { 2, 6 }, { 6, 2 }},
{{ 6, 3 }, { 3, 6 }, { 7, 0 }},
{{ 6, 4 }, { 4, 6 }, { 7, 1 }},
{{ 6, 5 }, { 5, 6 }, { 7, 2 }},
{{ 6, 6 }, { 6, 6 }, { 8, 0 }},
{{ 6, 7 }, { 7, 6 }, { 8, 1 }},
{{ 6, 8 }, { 8, 6 }, { 8, 2 }},
{{ 7, 0 }, { 0, 7 }, { 6, 3 }},
{{ 7, 1 }, { 1, 7 }, { 6, 4 }},
{{ 7, 2 }, { 2, 7 }, { 6, 5 }},
{{ 7, 3 }, { 3, 7 }, { 7, 3 }},
{{ 7, 4 }, { 4, 7 }, { 7, 4 }},
{{ 7, 5 }, { 5, 7 }, { 7, 5 }},
{{ 7, 6 }, { 6, 7 }, { 8, 3 }},
{{ 7, 7 }, { 7, 7 }, { 8, 4 }},
{{ 7, 8 }, { 8, 7 }, { 8, 5 }},
{{ 8, 0 }, { 0, 8 }, { 6, 6 }},
{{ 8, 1 }, { 1, 8 }, { 6, 7 }},
{{ 8, 2 }, { 2, 8 }, { 6, 8 }},
{{ 8, 3 }, { 3, 8 }, { 7, 6 }},
{{ 8, 4 }, { 4, 8 }, { 7, 7 }},
{{ 8, 5 }, { 5, 8 }, { 7, 8 }},
{{ 8, 6 }, { 6, 8 }, { 8, 6 }},
{{ 8, 7 }, { 7, 8 }, { 8, 7 }},
{{ 8, 8 }, { 8, 8 }, { 8, 8 }}
};
ushort comb91[] =
{
0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x100
};
ushort comb92[] =
{
0x3, 0x5, 0x6, 0x9, 0xA, 0xC, 0x11, 0x12, 0x14, 0x18,
0x21, 0x22, 0x24, 0x28, 0x30, 0x41, 0x42, 0x44, 0x48, 0x50,
0x60, 0x81, 0x82, 0x84, 0x88, 0x90, 0xA0, 0xC0, 0x101, 0x102,
0x104, 0x108, 0x110, 0x120, 0x140, 0x180
};
ushort comb93[] =
{
0x7, 0xB, 0xD, 0xE, 0x13, 0x15, 0x16, 0x19, 0x1A, 0x1C,
0x23, 0x25, 0x26, 0x29, 0x2A, 0x2C, 0x31, 0x32, 0x34, 0x38,
0x43, 0x45, 0x46, 0x49, 0x4A, 0x4C, 0x51, 0x52, 0x54, 0x58,
0x61, 0x62, 0x64, 0x68, 0x70, 0x83, 0x85, 0x86, 0x89, 0x8A,
0x8C, 0x91, 0x92, 0x94, 0x98, 0xA1, 0xA2, 0xA4, 0xA8, 0xB0,
0xC1, 0xC2, 0xC4, 0xC8, 0xD0, 0xE0, 0x103, 0x105, 0x106, 0x109,
0x10A, 0x10C, 0x111, 0x112, 0x114, 0x118, 0x121, 0x122, 0x124, 0x128,
0x130, 0x141, 0x142, 0x144, 0x148, 0x150, 0x160, 0x181, 0x182, 0x184,
0x188, 0x190, 0x1A0, 0x1C0
};
ushort comb94[] =
{
0xF, 0x17, 0x1B, 0x1D, 0x1E, 0x27, 0x2B, 0x2D, 0x2E, 0x33,
0x35, 0x36, 0x39, 0x3A, 0x3C, 0x47, 0x4B, 0x4D, 0x4E, 0x53,
0x55, 0x56, 0x59, 0x5A, 0x5C, 0x63, 0x65, 0x66, 0x69, 0x6A,
0x6C, 0x71, 0x72, 0x74, 0x78, 0x87, 0x8B, 0x8D, 0x8E, 0x93,
0x95, 0x96, 0x99, 0x9A, 0x9C, 0xA3, 0xA5, 0xA6, 0xA9, 0xAA,
0xAC, 0xB1, 0xB2, 0xB4, 0xB8, 0xC3, 0xC5, 0xC6, 0xC9, 0xCA,
0xCC, 0xD1, 0xD2, 0xD4, 0xD8, 0xE1, 0xE2, 0xE4, 0xE8, 0xF0,
0x107, 0x10B, 0x10D, 0x10E, 0x113, 0x115, 0x116, 0x119, 0x11A, 0x11C,
0x123, 0x125, 0x126, 0x129, 0x12A, 0x12C, 0x131, 0x132, 0x134, 0x138,
0x143, 0x145, 0x146, 0x149, 0x14A, 0x14C, 0x151, 0x152, 0x154, 0x158,
0x161, 0x162, 0x164, 0x168, 0x170, 0x183, 0x185, 0x186, 0x189, 0x18A,
0x18C, 0x191, 0x192, 0x194, 0x198, 0x1A1, 0x1A2, 0x1A4, 0x1A8, 0x1B0,
0x1C1, 0x1C2, 0x1C4, 0x1C8, 0x1D0, 0x1E0
};
struct _combination
{
ushort count;
ushort * array;
};
struct _combination comb[] =
{
{0,0},
{ sizeof(comb91)/sizeof(ushort), comb91 },
{ sizeof(comb92)/sizeof(ushort), comb92 },
{ sizeof(comb93)/sizeof(ushort), comb93 },
{ sizeof(comb94)/sizeof(ushort), comb94 },
};
#define group_type_row 0
#define group_type_col 1
#define group_type_reg 2
// 2^^BASE-1
#define MASK_INITIAL_STATE 0x1FF
#define get_bit_count_16(u) (BitsSetTable256[((unsigned char*)&(u))[0]] + BitsSetTable256[((unsigned char*)&(u))[1]])
#define get_bit_set_16(u) (((unsigned char*)&(u))[1]?LogTable256[((unsigned char*)&(u))[1]] + 0x8:LogTable256[((unsigned char*)&(u))[0]])
#define get_cellId(groupType, groupId, itemId) (group_to_cell[groupType][groupId][itemId])
#define get_groupId(cellId, groupType) (cell_to_group[cellId][groupType][0])
#define get_itemId(cellId, groupType) (cell_to_group[cellId][groupType][1])
#define num_to_bits(n) (1 << (n))
char solvedtable[BASE*BASE+1];
ushort masktable[BASE*BASE];
ushort checkmask[BASE*3];
ushort nfound;
typedef struct _state
{
ushort nCandidates;
ushort changedId;
ushort changedTo;
char solvedtable[BASE*BASE+1];
ushort masktable[BASE*BASE];
ushort checkmask[BASE*3];
ushort nfound;
struct _state * next;
}state, *pstate;
pstate state_stack = 0;
int popState(ushort *nCandidates, ushort * changedId, ushort * changedTo)
{
pstate to_del;
if(!state_stack)
return 0;
*nCandidates = state_stack->nCandidates;
*changedId = state_stack->changedId;
*changedTo = state_stack->changedTo;
memcpy(solvedtable, state_stack->solvedtable, sizeof(solvedtable));
memcpy(masktable, state_stack->masktable, sizeof(masktable));
memcpy(checkmask, state_stack->checkmask, sizeof(checkmask));
nfound = state_stack->nfound;
to_del = state_stack;
state_stack = state_stack->next;
free(to_del);
return 1;
}
void pushState(ushort nCandidates, ushort changedId, ushort changedTo)
{
pstate new_state = 0;
new_state = malloc(sizeof(state));
new_state->changedId = changedId;
new_state->changedTo = changedTo;
new_state->nCandidates = nCandidates;
memcpy(new_state->solvedtable, solvedtable, sizeof(solvedtable));
memcpy(new_state->masktable, masktable, sizeof(masktable));
memcpy(new_state->checkmask, checkmask, sizeof(checkmask));
new_state->nfound = nfound;
new_state->next = state_stack;
state_stack = new_state;
}
int findNextTrial(ushort *nCandidates, ushort * changedId, ushort * changedTo)
{
int i, j;
do
{
for(i = *changedId; i < BASE*BASE; i++)
{
if(get_bit_count_16(masktable[i]) == *nCandidates)
{
while(*changedTo != 0x100)
{
if(*changedTo == 0) *changedTo = 1;
else *changedTo <<= 1;
if(masktable[i] & *changedTo)
{
*changedId = i;
if(get_bit_set_16(*changedTo) == get_bit_set_16(masktable[i]))
return 0;
else
return 1;
}
}
*changedTo = 0;
}
}
*changedId = 0;
(*nCandidates)++;
}while( *nCandidates != 10);
return -1;
}
void initBuffers()
{
int i;
nfound = 0;
memset(checkmask, 0, sizeof(checkmask));
for( i = 0; i < BASE*BASE; i++ )
{
masktable[i] = MASK_INITIAL_STATE;
solvedtable[i] = '.';
}
solvedtable[BASE*BASE] = '\0';
}
void inputValues()
{
int i;
gets(solvedtable);
-
for( i = 0; i < BASE*BASE; i++ )
{
if( solvedtable[i] != '.' )
masktable[i] = num_to_bits(solvedtable[i] - '1');
}
}
void outputTable()
{
/*
----- -----
|. . * * *
| . * 1 *
| . * * *
----- -----
*/
int i, j, k;
for(i = 0; i < 9; i++)
{
if(i%3==0)
printf(" ----- ----- ----- ----- ----- ----- ----- ----- -----\n");
else
-
for(k = 0; k < 3; k++)
{
for(j = 0; j < 9; j++)
{
if(j % 3 == 0)
else
-
if(masktable[i*BASE+j] == 0)
{
if(k==1)
printf(" %c ", solvedtable
[i*BASE+j
]);
else
}else
printf("%c %c %c", num_to_bits
(k*
3 +
0)&masktable
[i*BASE+j
]?
'.':
' ',
num_to_bits(k*3 + 1)&masktable[i*BASE+j]?'.':' ',
num_to_bits(k*3 + 2)&masktable[i*BASE+j]?'.':' ');
}
}
}
-
printf(" ----- ----- ----- ----- ----- ----- ----- ----- -----\n");
}
#ifdef ONLINE_JUDGE
#define output_table()
#else
#define output_table() outputTable()
#endif
#define apply_mask(c) { \
ushort rowId = get_groupId(c, group_type_row); \
ushort colId = get_groupId(c, group_type_col); \
ushort regId = get_groupId(c, group_type_reg); \
ushort n = ~masktable[c] & MASK_INITIAL_STATE; \
if(checkmask[rowId] & masktable[c] || \
checkmask[BASE+colId] & masktable[c] || \
checkmask[BASE*2+regId] & masktable[c] ) \
return -1; \
checkmask[rowId] |= masktable[c]; \
checkmask[BASE+colId] |= masktable[c]; \
checkmask[BASE*2+regId] |= masktable[c]; \
solvedtable[c] = get_bit_set_16(masktable[c])+'1'; \
masktable[c] = 0; \
nfound++; \
if(applyMask(rowId, group_type_row, n) == -1) \
return -1; \
if(applyMask(colId, group_type_col, n) == -1) \
return -1; \
if(applyMask(regId, group_type_reg, n) == -1) \
return -1; \
}
int applyMask(ushort groupId, ushort groupType, ushort mask)
{
ushort i, c;
for(i = 0; i < BASE; i++)
{
c = get_cellId(groupType, groupId, i);
if( masktable[c] )
{
masktable[c] &= mask;
if(!masktable[c])
return -1;
if( get_bit_count_16(masktable[c]) == 1 )
apply_mask(c);
}
}
return 1;
}
int FindNaked1()
{
int i;
int found = 0;
for(i = 0; i < BASE*BASE; i++)
{
if(!masktable[i] && solvedtable[i]=='.')
{
found = -1;
break;
}
-
if(masktable[i] && get_bit_count_16(masktable[i]) == 1)
{
apply_mask(i);
found = 1;
}
}
return found;
}
int FindHidden1()
{
int i, j, k;
int found = 0;
ushort s_mask[3], o_mask[3], cell[3];
-
for(i = 0; i < BASE; i++)
{
for(k = 0; k < 9; k++)
{
s_mask[0]=s_mask[1]=s_mask[2]=0;
o_mask[0]=o_mask[1]=o_mask[2]=0;
-
for(j = 0; j < BASE; j++)
{
if(k == j)
{
#define or_smask(t) cell[t] = get_cellId(t, i, j); \
s_mask[t] |= masktable[cell[t]];
-
or_smask(group_type_row);
or_smask(group_type_col);
or_smask(group_type_reg);
#undef or_smask
}else
{
#define or_omask(t) o_mask[t] |= masktable[get_cellId(t, i, j)];
or_omask(group_type_row);
or_omask(group_type_col);
or_omask(group_type_reg);
#undef or_omask
}
}
#define and_smask(t) s_mask[t] &= ~o_mask[t];
-
and_smask(group_type_row);
and_smask(group_type_col);
and_smask(group_type_reg);
#undef and_smask
-
#define find_h(t) if(get_bit_count_16(s_mask[t]) == 1) \
{ \
ushort c = cell[t]; \
if(masktable[c]) \
{ \
masktable[c] = s_mask[t]; \
found = 1; \
apply_mask(c);\
} \
}
-
find_h(group_type_row);
find_h(group_type_col);
find_h(group_type_reg);
#undef find_h
}
}
-
return found;
}
int FindLocked()
{
int found = 0;
int i, j, k, g, c, t1, t2;
ushort s_mask[12], cell[12], and_mask[12], n, m;
for(i = 0; i < 9; i++)
{
for(j = 0; j < 12; j++)
{
k = j%3;
switch(j/3)
{
case 0:
cell[j] = get_cellId(group_type_reg, i, k*3);
s_mask[j] = masktable[cell[j]] | masktable[cell[j]+1] | masktable[cell[j]+2];
break;
case 1:
cell[j] = get_cellId(group_type_reg, i, k);
s_mask[j] = masktable[cell[j]] | masktable[cell[j]+BASE] | masktable[cell[j]+BASE*2];
break;
case 2:
cell[j] = get_cellId(group_type_row, i, k*3);
s_mask[j] = masktable[cell[j]] | masktable[cell[j]+1] | masktable[cell[j]+2];
break;
case 3:
cell[j] = get_cellId(group_type_col, i, k*3);
s_mask[j] = masktable[cell[j]] | masktable[cell[j]+BASE] | masktable[cell[j]+BASE*2];
break;
}
}
and_mask[0] = s_mask[0] & ~(s_mask[1] | s_mask[2]);
and_mask[1] = s_mask[1] & ~(s_mask[0] | s_mask[2]);
and_mask[2] = s_mask[2] & ~(s_mask[0] | s_mask[1]);
and_mask[3] = s_mask[3] & ~(s_mask[4] | s_mask[5]);
and_mask[4] = s_mask[4] & ~(s_mask[3] | s_mask[5]);
and_mask[5] = s_mask[5] & ~(s_mask[3] | s_mask[4]);
and_mask[6] = s_mask[6] & ~(s_mask[7] | s_mask[8]);
and_mask[7] = s_mask[7] & ~(s_mask[6] | s_mask[8]);
and_mask[8] = s_mask[8] & ~(s_mask[6] | s_mask[7]);
and_mask[9] = s_mask[9] & ~(s_mask[10] | s_mask[11]);
and_mask[10] = s_mask[10] & ~(s_mask[9] | s_mask[11]);
and_mask[11] = s_mask[11] & ~(s_mask[9] | s_mask[10]);
-
for(j = 0; j < 12; j++)
{
if(and_mask[j])
{
n = ~and_mask[j];
switch(j/3)
{
case 0:
t1 = group_type_reg;
t2 = group_type_row;
break;
case 1:
t1 = group_type_reg;
t2 = group_type_col;
break;
case 2:
t1 = group_type_row;
t2 = group_type_reg;
break;
case 3:
t1 = group_type_col;
t2 = group_type_reg;
break;
};
-
g = get_groupId(cell[j], t2);
-
for(k = 0; k < 9; k++)
{
c = get_cellId(t2, g, k);
if(get_groupId(c, t1) == i)
continue;
-
m = masktable[c];
masktable[c] &= n;
if(m != masktable[c])
found =1;
}
}
}
if(found)
break;
-
}
return found;
}
int FindNaked(char x, const char group_to_cell[9][9])
{
int i, j, k;
int found = 0;
ushort s_mask, o_mask, c, notfoundmask;
-
for(i = 0; i < BASE; i++)
{
notfoundmask = 0;
for(j = BASE-1; j>=0; j--)
{
notfoundmask <<=1;
if(masktable[group_to_cell[i][j]])
notfoundmask |= 1;
}
for(k = 0; k < comb[x].count; k++)
{
c = comb[x].array[k];
if((c & notfoundmask) != c)
continue;
s_mask = o_mask=0;
-
for(j = 0; j < BASE; j++)
{
if(c & 1)
s_mask |= masktable[group_to_cell[i][j]];
else
o_mask |= masktable[group_to_cell[i][j]];
c>>=1;
if( get_bit_count_16(s_mask) > x )
break;
}
if( get_bit_count_16(s_mask) == x )
{
s_mask = ~s_mask;
c = comb[x].array[k];
for(j = 0; j < BASE; j++)
{
if((c&1) == 0)
{
ushort m = masktable[group_to_cell[i][j]];
if((m & s_mask) != m)
{
masktable[group_to_cell[i][j]] = m & s_mask;
found = 1;
}
}
c>>=1;
}
}
if(found)
return 1;
}
}
-
return found;
}
int FindHidden(char x, const char group_to_cell[9][9])
{
int i, j, k;
int found = 0;
ushort s_mask, o_mask, c, notfoundmask;
-
for(i = 0; i < BASE; i++)
{
notfoundmask = 0;
for(j = BASE-1; j>=0; j--)
{
notfoundmask <<=1;
if(masktable[group_to_cell[i][j]])
notfoundmask |= 1;
}
for(k = 0; k < comb[x].count; k++)
{
c = comb[x].array[k];
if((c & notfoundmask) != c)
continue;
s_mask = o_mask=0;
-
for(j = 0; j < BASE; j++)
{
if(c & 1)
s_mask |= masktable[group_to_cell[i][j]];
else
o_mask |= masktable[group_to_cell[i][j]];
c>>=1;
}
s_mask &= ~o_mask;
if( get_bit_count_16(s_mask) == x )
{
c = comb[x].array[k];
for(j = 0; j < BASE; j++)
{
if((c&1) == 1)
{
ushort m = masktable[group_to_cell[i][j]];
if((m & s_mask) != m)
{
masktable[group_to_cell[i][j]] = m & s_mask;
found = 1;
}
}
c>>=1;
}
}
if(found)
return 1;
}
}
-
return found;
}
int FindNakedGen(char x, char *group)
{
int i;
for(i = 0; i < 3; i++)
{
if(++*group > group_type_reg)
*group = group_type_row;
if(FindNaked(x, group_to_cell[*group]))
return 1;
}
return 0;
}
int FindHiddenGen(char x, char *group)
{
int i;
for(i = 0; i < 3; i++)
{
if(++*group > group_type_reg)
*group = group_type_row;
if(FindHidden(x, group_to_cell[*group]))
return 1;
}
return 0;
}
void ProcessBox()
{
int found = 0;
char group[6] = {0};
ushort nCandidates, changedId, changedTo;
initBuffers();
inputValues();
do
{
do
{
found = FindNaked1();
if(found == -1)
break;
if(nfound == 81)
break;
output_table();
-
do
{
found = FindHidden1();
}while(found == 1 && nfound < 81);
if(found == -1)
break;
if(nfound == 81)
break;
output_table();
/*
found = FindLocked();
if(found)
continue;
-
found = FindNakedGen(2, &group[0]);
if(found)
continue;
-
found = FindHiddenGen(2, &group[1]);
if(found)
continue;
-
found = FindNakedGen(3, &group[2]);
if(found)
continue;
-
found = FindHiddenGen(3, &group[3]);
if(found)
continue;
found = FindNakedGen(4, &group[4]);
if(found)
continue;
-
found = FindHiddenGen(4, &group[5]);
if(found)
continue;
*/
// TODO:
// Find cross (x-wing, swordfish etc)
// Implement trial-and-error
}while(found == 1);
if(nfound == 81)
break;
-
if(found == 0)
{
nCandidates = 2;
changedId = 0;
changedTo = 0;
}else if(found == -1)
{
if(!popState(&nCandidates, &changedId, &changedTo))
{
puts("N");
return;
}
}
found = findNextTrial(&nCandidates, &changedId, &changedTo);
if(found == -1)
{
puts("N");
return;
}
if(found == 1)
pushState(nCandidates, changedId, changedTo);
masktable[changedId] = changedTo;
}while(1);
-
puts("Y");
puts(solvedtable);
while(popState(&nCandidates, &changedId, &changedTo));
}
int main()
{
int t;
char strT[5];
gets(strT);
t = atoi(strT);
while(t--)
ProcessBox();
return 0;
}
-