Skip to content

Instantly share code, notes, and snippets.

@NSG650
Created July 17, 2023 10:57
Show Gist options
  • Save NSG650/cd3ddb7a4a69efcfcfa5595c752bc2c5 to your computer and use it in GitHub Desktop.
Save NSG650/cd3ddb7a4a69efcfcfa5595c752bc2c5 to your computer and use it in GitHub Desktop.
Sudoku generator and then solves the generated puzzle.
#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