/* * Copyright (C) 2022 Camden Dixie O'Brien * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with this program. If not, see * . */ #include "solve.h" #include int solve(struct sudoku *sud) { unsigned r, c, n, i, j, val, np, pr, pc; bool match; for (n = 0;; ++n) { match = false; /* Check if only one place a value can go on each row. */ for (r = 0; r < NDIGITS; ++r) { for (val = 0; val < NDIGITS; ++val) { np = 0; for (c = 0; c < NDIGITS; ++c) { if (!sud->cells[r][c].det && sud->cells[r][c].pvals[val]) { pr = r; pc = c; ++np; if (np > 1) break; } } if (np == 1) { if (update(sud, pr, pc, val) != OK) return -1; match = true; } } } /* Check if only one place a value can go on each column. */ for (c = 0; c < NDIGITS; ++c) { for (val = 0; val < NDIGITS; ++val) { np = 0; for (r = 0; r < NDIGITS; ++r) { if (!sud->cells[r][c].det && sud->cells[r][c].pvals[val]) { pr = r; pc = c; ++np; if (np > 1) break; } } if (np == 1) { if (update(sud, pr, pc, val) != OK) return -1; match = true; } } } /* Check if only one place a value can go in each segment. */ for (i = 0; i < NDIGITS; ++i) { for (val = 0; val < NDIGITS; ++val) { np = 0; for (j = 0; j < NDIGITS; ++j) { r = SEGLEN * (i / SEGLEN) + j / SEGLEN; c = SEGLEN * (i % SEGLEN) + j % SEGLEN; if (!sud->cells[r][c].det && sud->cells[r][c].pvals[val]) { pr = r; pc = c; ++np; if (np > 1) break; } } if (np == 1) { if (update(sud, pr, pc, val) != OK) return -1; match = true; } } } /* Exit if no matches. */ if (!match) return n; } }