278 lines
4.6 KiB
C
278 lines
4.6 KiB
C
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <rlib.h>
|
||
|
#include "rsolve.h"
|
||
|
#define N 9
|
||
|
|
||
|
// VERSION 1
|
||
|
|
||
|
|
||
|
|
||
|
void clear()
|
||
|
{
|
||
|
printf("\e[2J");
|
||
|
fflush(stdout);
|
||
|
}
|
||
|
void print_grid(int grid[N][N])
|
||
|
{
|
||
|
for (int row = 0; row < N; row++)
|
||
|
{
|
||
|
for (int col = 0; col < N; col++)
|
||
|
{
|
||
|
printf("%d ", grid[row][col]);
|
||
|
}
|
||
|
printf("\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
unsigned int solve2(int grid[N][N], unsigned long long *attempts)
|
||
|
{
|
||
|
(*attempts)++;
|
||
|
// if(*attempts % 10000000 == 0)
|
||
|
// print_grid(grid);
|
||
|
unsigned int row, col;
|
||
|
bool emptySpot = false;
|
||
|
for (row = 0; row < N; row++)
|
||
|
{
|
||
|
for (col = 0; col < N; col++)
|
||
|
{
|
||
|
if (grid[row][col] == 0)
|
||
|
{
|
||
|
emptySpot = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (emptySpot)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (!emptySpot)
|
||
|
return true;
|
||
|
for (int num = 1; num <= 9; num++)
|
||
|
{
|
||
|
if (ris_safe(grid, row, col, num))
|
||
|
{
|
||
|
grid[row][col] = num;
|
||
|
|
||
|
if (solve2(grid, attempts))
|
||
|
{
|
||
|
return *attempts;
|
||
|
}
|
||
|
|
||
|
grid[row][col] = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
int solve(int grid[N][N], unsigned long long *steps)
|
||
|
{
|
||
|
*(steps)++;
|
||
|
|
||
|
// if(*steps % 1000000){
|
||
|
// printf("%lld\n",*steps);
|
||
|
// }
|
||
|
|
||
|
int col;
|
||
|
int row;
|
||
|
bool found_empty = false;
|
||
|
for (row = 0; row < N; row++)
|
||
|
{
|
||
|
for (col = 0; col < N; col++)
|
||
|
{
|
||
|
if (!grid[row][col])
|
||
|
{
|
||
|
found_empty = true;
|
||
|
}
|
||
|
}
|
||
|
if (found_empty)
|
||
|
break;
|
||
|
}
|
||
|
if (!found_empty)
|
||
|
return true;
|
||
|
for (int i = 1; i < 10; i++)
|
||
|
{
|
||
|
|
||
|
if (ris_safe(grid, row, col, i))
|
||
|
{
|
||
|
grid[row][col] = i;
|
||
|
|
||
|
if (solve(grid, steps))
|
||
|
{
|
||
|
print_grid(grid);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
grid[row][col] = 0;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
int get_next_int(FILE *f)
|
||
|
{
|
||
|
char c;
|
||
|
while ((c = getc(f)) && c != EOF)
|
||
|
{
|
||
|
if (c < '0' || c > '9')
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
return c - '0';
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
bool grid_read(int grid[N][N])
|
||
|
{
|
||
|
for (int row = 0; row < N; row++)
|
||
|
{
|
||
|
for (int col = 0; col < N; col++)
|
||
|
{
|
||
|
grid[row][col] = get_next_int(stdin);
|
||
|
clear();
|
||
|
print_grid(grid);
|
||
|
if (grid[row][col] == -1)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
} /*
|
||
|
1 2 3 4 5 6 9 7 8
|
||
|
4 5 6 7 8 9 1 2 3
|
||
|
7 8 9 3 2 1 6 4 5
|
||
|
9 4 7 8 3 2 5 1 6
|
||
|
2 6 8 9 1 5 7 3 4
|
||
|
5 3 1 6 7 0 0 0 0
|
||
|
0 0 0 0 0 0 0 0 0
|
||
|
0 0 0 0 0 0 0 0 0
|
||
|
0 0 0 0 0 0 0 0 0 */
|
||
|
|
||
|
/*
|
||
|
0 0 0 0 0 0 0 0 0
|
||
|
0 0 0 0 0 0 0 0 0
|
||
|
0 0 0 0 0 0 0 0 0
|
||
|
0 0 0 0 0 0 0 0 9
|
||
|
0 0 0 0 0 0 0 0 0
|
||
|
0 0 0 0 0 0 0 0 0
|
||
|
0 0 2 0 0 0 0 0 0
|
||
|
0 0 0 0 0 0 0 2 0
|
||
|
1 0 0 3 0 7 0 0 0
|
||
|
*/
|
||
|
bool is_empty(int grid[N][N])
|
||
|
{
|
||
|
for (int i = 0; i < N * N; i++)
|
||
|
{
|
||
|
if (grid[i / 9][i % 9] != 0)
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/* 27 secs with rsolve. Good test:
|
||
|
2 0 0 0 0 8 0 0 0
|
||
|
0 0 0 0 0 0 0 9 0
|
||
|
0 0 8 0 2 0 0 0 5
|
||
|
0 0 0 0 0 7 0 0 0
|
||
|
0 4 0 0 0 0 9 0 0
|
||
|
0 0 0 3 0 5 0 0 0
|
||
|
0 2 0 0 0 1 0 0 0
|
||
|
0 9 0 0 0 0 8 0 0
|
||
|
0 8 0 0 0 2 0 0 0
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
4:16
|
||
|
|
||
|
7 0 0 0 0 4 0 0 6
|
||
|
0 0 3 0 0 0 0 0 0
|
||
|
0 0 0 0 0 0 0 0 4
|
||
|
4 0 0 0 6 0 0 5 0
|
||
|
0 0 0 0 4 0 1 0 0
|
||
|
0 8 0 0 0 0 0 0 9
|
||
|
0 0 0 0 5 0 0 4 0
|
||
|
0 0 0 0 2 0 0 6 0
|
||
|
0 0 0 7 0 0 0 0 0
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
int main(int argc, char *argv[])
|
||
|
{
|
||
|
printf("Usage: ./solve [auto (optional)]\n");
|
||
|
printf(" run without parameters to provide your own grid. Many formats supported, XML, HTML, JSON, NO DELIMITER, DELMITED BY ANYTHING.\n");
|
||
|
RBENCH(1000000,{
|
||
|
int * g = rgenerate_puzzle(17);
|
||
|
free(g);
|
||
|
})
|
||
|
srand(time(NULL));
|
||
|
setbuf(stdout, 0);
|
||
|
int grid[N][N];
|
||
|
memset(grid, 0, N * N * sizeof(int));
|
||
|
clear();
|
||
|
int * ex_grid = rgenerate_puzzle(17);
|
||
|
printf("Paste grid in this format:\n");
|
||
|
print_grid(ex_grid);
|
||
|
// grid[8][8] = 9;
|
||
|
// grid[8][8] = 8;
|
||
|
while (argc != 2)
|
||
|
{
|
||
|
if (is_empty(grid))
|
||
|
while (!grid_read(grid))
|
||
|
{
|
||
|
printf("Invalid grid\n");
|
||
|
}
|
||
|
if (rvalidate_grid(grid))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
printf("Corrupt grid..\n");
|
||
|
memset(grid, 0, N * N * sizeof(int));
|
||
|
}
|
||
|
clear();
|
||
|
int grid_original[N][N];
|
||
|
if(argc == 2){
|
||
|
memcpy(grid, ex_grid, N * N * sizeof(int));
|
||
|
}
|
||
|
memcpy(grid_original, grid, N * N * sizeof(int));
|
||
|
printf("Grid valid. Solving...\n\n");
|
||
|
unsigned long long steps = 0;
|
||
|
nsecs_t start = nsecs();
|
||
|
RBENCH(1, {
|
||
|
memcpy(grid, grid_original, N * N * sizeof(int));
|
||
|
steps = 0;
|
||
|
if (rsolve(grid, &steps))
|
||
|
{
|
||
|
printf("original:\n");
|
||
|
print_grid(grid_original);
|
||
|
printf("\ncompleted:\n");
|
||
|
print_grid(grid);
|
||
|
printf("\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
});
|
||
|
printf("Steps: %u\n", steps);;
|
||
|
|
||
|
|
||
|
RBENCH(1, {
|
||
|
memcpy(grid, grid_original, N * N * sizeof(int));
|
||
|
steps = 0;
|
||
|
if (solve2(grid, &steps)){
|
||
|
printf("%s","2");
|
||
|
}
|
||
|
memcpy(grid, grid_original, N * N * sizeof(int));
|
||
|
});
|
||
|
printf("Steps: %u\n", steps);;
|
||
|
|
||
|
nsecs_t end = nsecs();
|
||
|
|
||
|
printf("Duration: %s\n", format_time(end - start));
|
||
|
return 0;
|
||
|
}
|