#include <stdio.h>
char solve(char (*)[5], const char *, const char *);
void findNextField(const char (*)[5], const char *, const char *, char *, char *);
char solveRec(const char (*)[5], const char *, const char *,
char *, char *, char *, char *, unsigned long, char, char);
void findNextField(const char (*data)[5], const char *rowcount,
const char *colcount, char *y, char *x)
{
char roworcol, max, maxindex, i;
if(*y >= 0 && *y < 5 && *x >= 0 && *x < 5)
{
if(rowcount[*y] < 5)
{
*x = 0;
while(data[*y][*x])
(*x)++;
return;
}
if(colcount[*x] < 5)
{
*y = 0;
while(data[*y][*x])
(*y)++;
return;
}
}
max = -1;
roworcol = -1;
for(i = 0; i < 5; i++)
{
if(rowcount[i] > max && rowcount[i] < 5)
{
roworcol = 0;
max = rowcount[i];
maxindex = i;
if(max == 4)
break;
}
}
if(max < 4)
{
for(i = 0; i < 5; i++)
{
if(colcount[i] > max && colcount[i] < 5)
{
roworcol = 1;
max = colcount[i];
maxindex = i;
}
if(max == 4)
break;
}
}
if(roworcol == 1)
{
*x = maxindex;
*y = 0;
while(data[*y][*x])
(*y)++;
}
else if(roworcol == 0)
{
*y = maxindex;
*x = 0;
while(data[*y][*x])
(*x)++;
}
return;
}
char solveRec(char (*data)[5], const char *rowsum, const char *colsum,
char *currentrowsum, char *currentcolsum, char *rowcount, char *colcount,
unsigned long usedmask, char y, char x)
{
char nexty, nextx, minz, maxz;
if((usedmask/2) == ((1<<25)-1))
return 0;
minz = 1;
maxz = 25;
if(rowcount[y] == 4)
{
minz = maxz = rowsum[y] - currentrowsum[y];
if(colcount[x] == 4 && minz != (colsum[x] - currentcolsum[x]))
maxz = 0;
}
else if(colcount[x] == 4)
{
minz = maxz = colsum[x] - currentcolsum[x];
}
else
{
while(usedmask&(1<<minz)) minz++;
while(usedmask&(1<<maxz)) maxz--;
}
if(minz > maxz || minz < 1 || maxz > 25) return 1;
nexty = y;
nextx = x;
rowcount[y]++;
colcount[x]++;
data[y][x] = -1;
findNextField(data, rowcount, colcount, &nexty, &nextx);
while(minz <= maxz)
{
if(usedmask&(1<<minz))
{
minz++;
continue;
}
data[y][x] = minz;
currentrowsum[y] += minz;
currentcolsum[x] += minz;
usedmask |= (1<<minz);
if(!solveRec(data, rowsum, colsum, currentrowsum, currentcolsum,
rowcount, colcount, usedmask, nexty, nextx))
return 0;
usedmask &= ~(1<<minz);
currentcolsum[x] -= minz;
currentrowsum[y] -= minz;
minz++;
}
data[y][x] = 0;
rowcount[y]--;
colcount[x]--;
return 1;
}
char solve(char (*data)[5], const char *rowsum, const char *colsum)
{
unsigned long usedmask = 0;
char y, x;
char rowcount[5], colcount[5];
char currentrowsum[5], currentcolsum[5];
for(y = 0; y < 5; y++)
{
rowcount[y] = 0;
colcount[y] = 0;
currentrowsum[y] = 0;
currentcolsum[y] = 0;
}
for(y = 0; y < 5; y++)
{
if(rowsum[y] < 15 || rowsum[y] > 115 || colsum[y] < 15 || colsum[y] > 115)
return -1;
for(x = 0; x < 5; x++)
{
if(data[y][x] < 0 || data[y][x] > 25)
return -1;
if(data[y][x])
{
if(usedmask & (1<<data[y][x]))
return -1;
usedmask |= (1<<data[y][x]);
rowcount[y]++;
colcount[x]++;
currentrowsum[y] += data[y][x];
currentcolsum[x] += data[y][x];
}
}
}
if((usedmask/2) == ((1<<25)-1))
return 0;
y = -1;
x = -1;
findNextField(data, rowcount, colcount, &y, &x);
return solveRec(data, rowsum, colsum, currentrowsum, currentcolsum,
rowcount, colcount, usedmask, y, x);
}
int main(int argc, char *argv[])
{
char data[5][5] = {
{0,0,20,0,0},
{2,17,0,10,0},
{0,1,13,0,0},
{0,0,0,24,0},
{15,0,0,0,3},
};
char rowsum[5] = {78, 69, 73, 56, 49};
char colsum[5] = {66, 54, 62, 77, 66};
char y, x, r;
r = solve(data, rowsum, colsum);
if(r < 0)
printf("Error\n");
else if(r > 0)
printf("No solution\n");
else
{
for(y = 0; y < 5; y++)
{
for(x = 0; x < 5; x++)
printf("%.2d ", data[y][x]);
printf("\n");
}
}
return 0;
}