def encuentra_prox_vacio(puzzle): """ Encuentra la próxima fila, columna del puzzle sin llenar (están representadas como -1) retorna tupla (indice fila, indice columna) o (None, None) en caso de no existir. """ for f in range(9): for c in range(9): if puzzle[f][c] == -1: return f, c return None, None def es_valida(puzzle, intento, fil, col): """ Valida el intento en fila/columna retorna True si es valida, Falso si no. """ # comenzar con los valores de fila: fil_vals = puzzle[fil] if intento in fil_vals: return False # ahora los valores de columna #col_vals = [] #for i in range(9): # col_vals.append(puzzle[i][col]) col_vals = [puzzle[i][col] for i in range(9)] if intento in col_vals: return False # ahora el bloque 3x3 # encontrar donde empieza cada bloque, e iterar sobre # los 3 valores de fila/columna fil_start = (fil // 3) * 3 col_start = (col // 3) * 3 for f in range(fil_start, fil_start + 3): for c in range(col_start, col_start +3): if puzzle[f][c] == intento: return False # Al llegar aquí el intento es válido return True def resolver_sodoku(puzzle): """ Resuelve sodoku usando 'backtracking'. El puzzle es una lista de listas, donde cada lista interna es una fila en el puzzle. retorna exista solución o no. """ # paso 1: Escoger un lugar en el puzzle para intetar solución fil, col = encuentra_prox_vacio(puzzle) # paso 1.1: Validación if fil is None: return True # paso 2: Si hay lugar para poner un número, entonces hace un intento (1-9) for intento in range(1, 10): # paso 3: validar posición if es_valida(puzzle, intento, fil, col): # paso 3.1: intento validado, proceder con la jugada puzzle[fil][col] = intento # paso 4: llamado recursivo a funcion resolver_sodoku() if resolver_sodoku(puzzle): return True # paso 5: si el intento no es válido o no resuelve el puzzle # entoncens retroceder un paso y haver nuevo intento puzzle[fil][col] = -1 # resetea el intento # paso 6: si ningún intento funcion entonves el puzzle no tiene solución return False if __name__ == '__main__': tablero_ejemplo = [ [3, 9, -1, -1, 5, -1, -1, -1, -1], [-1, -1, -1, 2, -1, -1, -1, -1, 5], [-1, -1, -1, 7, 1, 9, -1, 8, -1], [-1, 5, -1, -1, 6, 8, -1, -1, -1], [2, -1, 6, -1, -1, 3, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1, -1, 4], [5, -1, -1, -1, -1, -1, -1, -1, -1], [6, 7, -1, 1, -1, 5, -1, 4, -1], [1, -1, 9, -1, -1, -1, 2, -1, -1] ] print(resolver_sodoku(tablero_ejemplo)) print(tablero_ejemplo)