|
#ifndef SUDOKU_H
|
|
#define SUDOKU_H
|
|
|
|
#include "rlib.h"
|
|
#include "rsolve.h"
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#define ANSII_BLUE_BG "\033[34m"
|
|
#define ANSII_RED_BG "\033[31m"
|
|
#define ANSII_GREEN_BG "\033[32m"
|
|
#define ANSII_CLEAR "\033[0m"
|
|
|
|
#define N 9
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void draw_cell(int c)
|
|
{
|
|
if (c > 0 && c <= 3)
|
|
{
|
|
printf("%s", ANSII_BLUE_BG);
|
|
}
|
|
else if (c > 0 && c <= 6)
|
|
{
|
|
printf("%s", ANSII_GREEN_BG);
|
|
}
|
|
else if (c > 0 && c <= 9)
|
|
{
|
|
printf("%s", ANSII_RED_BG);
|
|
}
|
|
if(c){
|
|
printf("%s%d ", c > 9 ? "" :" ", c );
|
|
}else{
|
|
printf(" 0 ");
|
|
}
|
|
printf("%s", ANSII_CLEAR);
|
|
}
|
|
|
|
char * grid_to_string(int grid[N][N]){
|
|
static char result[1024];
|
|
result[0] = 0;
|
|
for (int row = 0; row < N; row++) {
|
|
for (int col = 0; col < N; col++) {
|
|
char chunk[4];
|
|
chunk[0] = 0;
|
|
sprintf(chunk,"%d ",grid[row][col]);
|
|
strcat(result,chunk);
|
|
}
|
|
strcat(result,"\n");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void print_grid(int grid[N][N],bool clear) {
|
|
if(clear)
|
|
printf("\033[2J\033[H");
|
|
for (int row = 0; row < N; row++) {
|
|
for (int col = 0; col < N; col++) {
|
|
draw_cell(grid[row][col]);
|
|
///printf("%d ", grid[row][col]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
int count_neighbors2(int grid[N][N],int row, int col){
|
|
// Check row
|
|
int num = -1;
|
|
int neighbors = 0;
|
|
for (int x = 0; x < N; x++) {
|
|
if(grid[row][x])
|
|
neighbors++;
|
|
if (grid[row][x] == num) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Check column
|
|
for (int x = 0; x < N; x++) {
|
|
if(grid[x][col])
|
|
neighbors++;
|
|
if (grid[x][col] == num) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Check box
|
|
int startRow = row - row % (N / 3), startCol = col - col % (N / 3);
|
|
for (int i = 0; i < N / 3; i++) {
|
|
for (int j = 0; j < N / 3; j++) {
|
|
if(grid[i + startRow][j + startCol])
|
|
neighbors++;
|
|
if (grid[i + startRow][j + startCol] == num) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
return neighbors;
|
|
}
|
|
|
|
int is_safe(int grid[N][N], int row, int col, int num) {
|
|
//if(count_neighbors(grid, row,col) < 4)
|
|
// return false;
|
|
// Check row
|
|
for (int x = 0; x < N; x++) {
|
|
if (grid[row][x] == num) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Check column
|
|
for (int x = 0; x < N; x++) {
|
|
if (grid[x][col] == num) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Check box
|
|
int startRow = row - row % (N / 3), startCol = col - col % (N / 3);
|
|
for (int i = 0; i < N / 3; i++) {
|
|
for (int j = 0; j < N / 3; j++) {
|
|
if (grid[i + startRow][j + startCol] == num) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void grid_reset(int * grid){
|
|
memset(grid,0,N*N*sizeof(int));
|
|
}
|
|
int * grid_copy(int * grid){
|
|
int * new_grid = malloc(N*N*sizeof(int));
|
|
memcpy(new_grid,grid,N*N*sizeof(int));
|
|
return new_grid;
|
|
}
|
|
|
|
int * grid_new(){
|
|
return (int *)calloc(sizeof(int),N*N);
|
|
}
|
|
|
|
|
|
|
|
|
|
bool empty_spot_is_available(int grid[N][N]){
|
|
for (unsigned int row = 0; row < N; row++) {
|
|
for (unsigned int col = 0; col < N; col++) {
|
|
if (grid[row][col] == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
unsigned long long _solve(int grid[N][N], unsigned long long *attempts, bool draw){
|
|
(*attempts)++;
|
|
unsigned int row, col;
|
|
if(!get_easiest_cell(grid,&row,&col)){
|
|
//print_grid(grid, false);
|
|
return *attempts;
|
|
}
|
|
for(int num = 1; num < N + 1; num++){
|
|
if(is_safe(grid,row,col,num)){
|
|
grid[row][col] = num;
|
|
//print_grid(grid,true);
|
|
if(_solve(grid,attempts,draw))
|
|
{
|
|
return *attempts;
|
|
}
|
|
grid[row][col] = 0;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
unsigned int _solve2(int grid[N][N], unsigned long long * attempts, bool draw) {
|
|
(*attempts)++;
|
|
unsigned int row, col;
|
|
bool emptySpot = false;
|
|
|
|
for (row = 0; row < N; row++) {
|
|
for (col = 0; col < N; col++) {
|
|
if (grid[row][col] == 0) {
|
|
// if(count_neighbors(grid,row,col) == 8){
|
|
|
|
// print_grid(grid,true);
|
|
// printf("Found neighbors\n");
|
|
// exit(0);
|
|
//}
|
|
emptySpot = true;
|
|
break;
|
|
}
|
|
}
|
|
if (emptySpot) {
|
|
break;
|
|
}
|
|
}
|
|
if(!emptySpot)
|
|
return true;
|
|
/*
|
|
if (!empty_spot_is_available(grid)) {
|
|
return true;
|
|
}*/
|
|
|
|
for (int num = 1; num <= 9; num++) {
|
|
//unsigned int * easy_row = calloc(sizeof(int),1);
|
|
//unsigned int * easy_col = calloc(sizeof(int), 1);
|
|
//if(get_easiest_cell(grid,easy_row,easy_col)){
|
|
// row = *easy_row;
|
|
// free(easy_row);
|
|
// col = *easy_col;
|
|
// free(easy_col);
|
|
|
|
//}
|
|
if (is_safe(grid, row, col, num)) {
|
|
grid[row][col] = num;
|
|
if(draw)
|
|
print_grid(grid,true);
|
|
|
|
if (_solve2(grid,attempts,draw)) {
|
|
return *attempts;
|
|
}
|
|
|
|
grid[row][col] = 0;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
unsigned int solve2(int grid[N][N], bool draw){
|
|
unsigned long long attempts = 0;
|
|
return _solve(grid,&attempts, draw);
|
|
}
|
|
|
|
unsigned int solve(int grid[N][N],bool draw) {
|
|
unsigned long long attempts = 0;
|
|
return _solve2(grid,&attempts, draw);
|
|
}
|
|
|
|
#endif
|
|
|