Created
July 17, 2023 10:57
-
-
Save NSG650/cd3ddb7a4a69efcfcfa5595c752bc2c5 to your computer and use it in GitHub Desktop.
Sudoku generator and then solves the generated puzzle.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <stddef.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
#include <time.h> | |
/* | |
uint8_t sudoku_input_board[81] = { | |
0, 0, 8, 0, 6, 1, 0, 0, 0, | |
6, 0, 4, 0, 0, 7, 5, 0, 0, | |
0, 0, 3, 0, 0, 0, 0, 0, 2, | |
8, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 9, 7, 5, 0, 6, 8, 2, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 7, | |
2, 0, 0, 0, 0, 0, 7, 0, 0, | |
0, 0, 6, 4, 0, 0, 2, 0, 5, | |
0, 0, 0, 8, 2, 0, 4, 0, 0 | |
}; | |
*/ | |
bool sudoku_is_number_placement_valid(uint8_t *board, size_t x, size_t y, uint8_t n) { | |
size_t cx = 3 * (x / 3); | |
size_t cy = 3 * (y / 3); | |
for (size_t i = 0; i < 9; i++) { | |
if (board[(x * 9) + i] == n) | |
return false; | |
if (board[(i * 9) + y] == n) | |
return false; | |
if (board[((cx + (i % 3)) * 9) + (cy + (i / 3))] == n) | |
return false; | |
} | |
return true; | |
} | |
ssize_t* sudoku_get_next_empty_box(uint8_t *board) { | |
ssize_t *coordinates = malloc(sizeof(size_t) * 2); | |
coordinates[0] = -1; | |
coordinates[1] = -1; | |
for (size_t x = 0; x < 9; x++) { | |
for (size_t y = 0; y < 9; y++) { | |
if (!board[(x * 9) + y]) { | |
coordinates[0] = x; | |
coordinates[1] = y; | |
break; | |
} | |
} | |
} | |
return coordinates; | |
} | |
bool sudoku_validate_array(uint8_t *array) { | |
for (size_t x = 0; x < 9; x++) { | |
for (size_t y = 0; y < 9; y++) { | |
if (x != y) | |
if (array[x] == array[y]) | |
return false; | |
} | |
} | |
return true; | |
} | |
bool sudoku_solve_board(uint8_t *board) { | |
size_t *coordinates = sudoku_get_next_empty_box(board); | |
if (coordinates[0] != -1 && coordinates[1] != -1) { | |
for (uint8_t n = 1; n < 10; n++) { | |
if (sudoku_is_number_placement_valid(board, | |
coordinates[0], | |
coordinates[1], n)) { | |
board[(coordinates[0] * 9) + coordinates[1]] = n; | |
if(sudoku_solve_board(board)) | |
return true; | |
board[(coordinates[0] * 9) + coordinates[1]] = 0; | |
} | |
} | |
} | |
else { | |
return true; | |
} | |
return false; | |
} | |
void sudoku_does_board_have_unique_solution(uint8_t *board, size_t *count) { | |
ssize_t *coordinates = sudoku_get_next_empty_box(board); | |
if (coordinates[0] != -1 && coordinates[1] != -1) { | |
for (uint8_t n = 1; n < 10; n++) { | |
if (sudoku_is_number_placement_valid(board, | |
coordinates[0], | |
coordinates[1], n)) { | |
board[(coordinates[0] * 9) + coordinates[1]] = n; | |
sudoku_does_board_have_unique_solution(board, count); | |
} | |
board[(coordinates[0] * 9) + coordinates[1]] = 0; | |
} | |
} | |
else { | |
// for some reason *count++ did not work :/ | |
count[0]++; | |
return; | |
} | |
} | |
void sudoku_dump_puzzle(uint8_t *board) { | |
//printf("\n__________________\n"); | |
for (size_t x = 0; x < 9; x++) { | |
for (size_t y = 0; y < 9; y++) { | |
//if (board[(x * 9) + y]) | |
printf("%hhx ", board[(x * 9) + y]); | |
//else | |
// printf(" |"); | |
} | |
//printf("\n__________________\n"); | |
printf("\n"); | |
} | |
} | |
size_t sudoku_get_random_cell_index(void) { | |
return (size_t)(rand() % 81); | |
} | |
uint8_t sudoku_get_random_cell_value(void) { | |
return (uint8_t)(rand() % 10); | |
} | |
size_t sudoku_get_clue_cell_count(uint8_t *board) { | |
size_t count = 0; | |
for (size_t x = 0; x < 9; x++) { | |
for (size_t y = 0; y < 9; y++) { | |
if (board[(x * 9) + y]) | |
count++; | |
} | |
} | |
return count; | |
} | |
int main(void) { | |
// initialise rand | |
srand(time(NULL)); | |
printf("Hello, World!\n"); | |
uint8_t sudoku_initial_board[81] = {0}; | |
// choose a random spot and put a random value | |
for (size_t i = 0; i < 3; i++) { | |
size_t index = sudoku_get_random_cell_index(); | |
uint8_t value = sudoku_get_random_cell_value(); | |
sudoku_initial_board[index] = value; | |
} | |
sudoku_dump_puzzle(sudoku_initial_board); | |
printf("\n"); | |
if(sudoku_solve_board(sudoku_initial_board)) | |
sudoku_dump_puzzle(sudoku_initial_board); | |
size_t count_of_clue_cells = sudoku_get_clue_cell_count(sudoku_initial_board); | |
printf("count_of_clue_cells: %lu\n", count_of_clue_cells); | |
for (size_t index = 0; index < 81; index++) { | |
uint8_t old_value = sudoku_initial_board[index]; | |
sudoku_initial_board[index] = 0; | |
size_t solution_count = 0; | |
sudoku_does_board_have_unique_solution(sudoku_initial_board, &solution_count); | |
if (solution_count < 2) | |
continue; | |
else { | |
sudoku_initial_board[index] = old_value; | |
} | |
count_of_clue_cells = sudoku_get_clue_cell_count(sudoku_initial_board); | |
printf("count_of_clue_cells: %lu\n", count_of_clue_cells); | |
} | |
printf("\n\n"); | |
sudoku_dump_puzzle(sudoku_initial_board); | |
size_t solution_count = 0; | |
sudoku_does_board_have_unique_solution(sudoku_initial_board, &solution_count); | |
printf("Solution count: %ld\n\n", solution_count); | |
if(sudoku_solve_board(sudoku_initial_board)) | |
sudoku_dump_puzzle(sudoku_initial_board); | |
else | |
printf("Ayo????\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment