#include #include #include #define UNDEFINED -1 #define VALUE_TYPE_UNDEFINED UNDEFINED #define VALUE_TYPE_STATIC 0 #define VALUE_TYPE_GUESS 1 #define COLOR_BLACK 0 #define COLOR_RED 1 #define COLOR_GREEN 2 #define COLOR_YELLOW 3 #define COLOR_BLUE 4 #define COLOR_MAGENTA 5 #define COLOR_CYAN 6 #define COLOR_WHITE 7 #define COLOR_FG 30 #define COLOR_BG 40 struct Value { int valueType; int value; }; /* int sudoku[9][9] = { {5, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 1, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 4, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 1, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 2}, {7, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 3, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 5, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 7, 3, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 6, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, 2, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 6, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 4, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, 9, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 8, 3, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, 8, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 4, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 2}, {4, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 6, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 7, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 1, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, 9} }; */ struct Value sudoku[9][9] = { {{VALUE_TYPE_STATIC, 5}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 1}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 4}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 1}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 2}}, {{VALUE_TYPE_STATIC, 7}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 3}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 5}, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 7}, {VALUE_TYPE_STATIC, 3}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 6}, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 2}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 6}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 4}, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 9}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 8}, {VALUE_TYPE_STATIC, 3}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 8}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 4}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 2}}, {{VALUE_TYPE_STATIC, 4}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 6}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 7}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}}, {{VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 1}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_UNDEFINED, UNDEFINED}, {VALUE_TYPE_STATIC, 9}} }; int calculateRow(int q, int f) { return (q / 3) * 3 + (f / 3); } int calculateCol(int q, int f) { return (q % 3) * 3 + (f % 3); } int calculateQuadrat(int row, int col) { return (row / 3) * 3 + col / 3; } int calculateField(int row, int col) { return (row % 3) * 3 + col % 3; } // checks if this value is present anywhere in the row bool isInRow(int row, int val) { for (int col = 0; col < 9; col++) { int q = calculateQuadrat(row, col); int f = calculateField(row, col); if (sudoku[q][f].valueType != VALUE_TYPE_UNDEFINED && sudoku[q][f].value == val) { return true; } } return false; } // checks if this value is present anywhere in the col bool isInCol(int col, int val) { for (int row = 0; row < 9; row++) { int q = calculateQuadrat(row, col); int f = calculateField(row, col); if (sudoku[q][f].valueType != VALUE_TYPE_UNDEFINED && sudoku[q][f].value == val) { return true; } } return false; } // checks if this value is present anywhere in the quadrat bool isInQuadrat(int q, int val) { for (int f = 0; f < 9; f++) { if (sudoku[q][f].valueType != VALUE_TYPE_UNDEFINED && sudoku[q][f].value == val) { return true; } } return false; } // check if val is possible value // i.e. not in row, not in col, not in q bool check(int q, int f, int val) { int row = calculateRow(q, f); int col = calculateCol(q, f); return !isInRow(row, val) && !isInCol(col, val) && !isInQuadrat(q, val); } void printDumpSudoku() { printf("\033[H\033[J"); for (int row = 0; row < 9; row++) { if (row % 3 == 0) { printf("+-------+-------+-------+\n"); } for (int col = 0; col < 9; col++) { if (col % 3 == 0) { if (col != 0) { printf(" "); } printf("|"); } int q = calculateQuadrat(row, col); int f = calculateField(row, col); if (sudoku[q][f].valueType != VALUE_TYPE_UNDEFINED) { int color; if (sudoku[q][f].valueType == VALUE_TYPE_STATIC) { color = COLOR_FG + COLOR_BLUE; } else if (sudoku[q][f].valueType == VALUE_TYPE_GUESS) { color = COLOR_FG + COLOR_GREEN; } printf(" \033[%dm%d\033[0m", color, sudoku[q][f].value); } else { printf(" -"); } } printf(" |\n"); } printf("+-------+-------+-------+\n"); } int main() { long iterations = 0; long guesses = 0; for (int q = 0; q < 9; q++) { for (int f = 0; f < 9; f++) { if (sudoku[q][f].valueType == VALUE_TYPE_STATIC) { continue; } iterations++; // initialize start value // might not be 1 if this field was already guessed but we had to go back // because the guessed value failed later int startVal; if (sudoku[q][f].value > UNDEFINED) { startVal = sudoku[q][f].value + 1; } else { startVal = 1; } // loop through values, if one possible value is found (value is neither in row nor in column) // continue to next field for (int val = startVal; val <= 9 && sudoku[q][f].valueType == VALUE_TYPE_UNDEFINED; val++) { if (check(q, f, val)) { sudoku[q][f].valueType = VALUE_TYPE_GUESS; sudoku[q][f].value = val; } } // check if a possible value was found // if not, go backwards to last guessed value if (sudoku[q][f].valueType == VALUE_TYPE_UNDEFINED) { // reset value for next time we get back at // this position for a guess sudoku[q][f].value = UNDEFINED; while (sudoku[q][f].valueType != VALUE_TYPE_GUESS) { f--; if (f < 0) { q--; if (q < 0) { fprintf(stderr, "Error: going backwards made q < 0\n"); return 1; } f = 8; } } sudoku[q][f].valueType = VALUE_TYPE_UNDEFINED; f--; // next iteration will increment f at beginning (for loop) } else { // good, possible value found //printDumpSudoku(); //usleep(10 * 1000); guesses++; } } } printDumpSudoku(); printf("Iterations: %ld\n", iterations); printf("Guesses: %ld\n", guesses); return 0; }