Commit 897c2dc7 authored by Zéfling's avatar Zéfling 🎨

Projet de résolution de Sudoku réalisé lors d'un TP Java

parents
/*
Copyright © 2014-05-12, Zéfling
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
The Software is provided "as is", without warranty of any kind, express or implied, including but
not limited to the warranties of merchantability, fitness for a particular purpose and
noninfringement. In no event shall the authors or copyright holders X be liable for any claim,
damages or other liability, whether in an action of contract, tort or otherwise, arising from,
out of or in connection with the software or the use or other dealings in the Software.
Except as contained in this notice, the name of the Zéfling shall not be used in
advertising or otherwise to promote the sale, use or other dealings in this Software without prior
written authorization from the Zéfling.
*/
package com.tp.test;
public class Sudoku {
private static int compteur = 0;
private static int compteurRecur = 0;
private static long[] temps = new long[2];
/** exemple de grille (0 pour les cases vides) */
private static int grille[][] = {
{9, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 7, 0, 0, 0, 4, 2, 0, 0},
{4, 0, 1, 0, 0, 3, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 7, 1, 0, 8},
{0, 5, 0, 0, 6, 0, 9, 7, 0},
{0, 0, 0, 5, 0, 0, 0, 2, 0},
{7, 0, 0, 4, 0, 0, 0, 3, 6},
{1, 0, 0, 0, 0, 2, 0, 0, 0}
};
private static int save[][];
public static void main(String[] args) {
// savegarde de la table pour l'affichage
save = new int[9][];
for(int i = 0; i < grille.length; i++) {
save[i] = grille[i].clone();
}
// grille d'origine
// afficher(grille);
temps[0] = System.nanoTime();
Sudoku s = new Sudoku();
if (compteur == 0) {
System.out.println("Pas de solution.");
} else {
System.out.println(compteur + " solution trouvée.");
}
System.out.println(compteurRecur);
}
public Sudoku(){
resoudre (grille, 0, 0);
}
/**
* Méthode récusive pour compléter le grille de sodoku
* @param g grille courante de sodoku
* @param a curseur en x
* @param b curseur en y
*/
public void resoudre (int[][] g, int a, int b) {
compteurRecur++;
// retour à la ligne si b arrive hors du tableau
if (b == 9) {
b = 0;
a++;
}
// si on arrive en bout de tableau, puis tester si on peut l'afficher
if (a == 9 && b == 0) {
if (test_grille(g)) {
temps[1] = System.nanoTime();
compteur++;
System.out.println("Solution : "+compteur);
System.out.println("en "+((temps[1] - temps[0]) / 1e9 )+" s.");
afficher(g);
//temps[0] = System.nanoTime();
}
}
//
else {
boolean numeros[];
// si la case est vide (teste sur la grille d'origine)
if (grille[a][b] == 0) {
numeros = numeros_possibles(grille, a, b);
// s'il a des valeurs possibles et liste chacune des possiblités
if (numeros[0]) {
for(int k = 1; k < 10; k++) {
if (numeros[k]) {
g[a][b] = k;
if (calcul_ligne(g, a) <= 45 && calcul_colonne(g, b) <= 45 && calcul_bloc(g, a, b) <= 45) {
resoudre(g, a , b + 1);
}
}
}
g[a][b] = 0;
}
}
// s'il y a déjà une valeur, avancer sur la grille
else {
resoudre(g, a , b + 1);
}
}
}
/**
* Tester si la grille est complète
* @param g la grille
* @return si elle est valide
*/
private boolean test_grille(int[][] g) {
for (int i = 0; i < 9; i ++) {
if (calcul_ligne(g, i) != 45) return false;
if (calcul_colonne(g, i) != 45) return false;
}
return true;
}
/**
* Récupérer les valeurs non utilisé pour la case courante
* @param g la grille en cours d'utilisation
* @param x position en x sur la grille
* @param y position en y sur la grille
* @return la listes des numéros jouables
*/
public boolean[] numeros_possibles (int[][] g, int x, int y) {
boolean[] t = new boolean[10];
int i, j;
for(i = 1; i < 10; i++) {
t[i] = true;
}
// lister les numeros sur la versticale et l'horizontale
for(i = 0; i < 9; i++) {
if(g[i][y] != 0) {
if (!t[0]) t[0] = true;
t[g[i][y]] = false;
}
if (g[x][i] != 0) {
if (!t[0]) t[0] = true;
t[g[x][i]] = false;
}
}
// lister les numeros dans le carré 3×3 courant
int v = (x / 3) * 3;
int h = (y / 3) * 3;
for(i = v; i < v + 3; i++) {
for(j = h; j < h + 3; j++) {
if(g[i][j] != 0) {
if (!t[0]) t[0] = true;
t[g[i][j]] = false;
}
}
}
return t;
}
/**
* tester si la valeur est dans le tableau
* @param tab le tableau
* @param val la valeur à tester
* @return vrai si elle y est.
*/
public boolean in_array (int[] tab, int val) {
int l = tab.length;
for(int i = 0; i < l; i++) {
if (tab[i] == val) return true;
}
return false;
}
/**
* la somme des nombres sur une colonne
* @param grille grille courante
* @param j numéro de la colonne
* @return la somme des nombres
*/
public int calcul_colonne (int[][] grille, int j) {
int t = 0;
for(int i = 0; i < 9; i++) {
t += grille[i][j];
}
return t;
}
/**
* la somme des nombres sur une ligne
* @param grille grille courante
* @param i numéro de la ligne
* @return la somme des nombres
*/
public int calcul_ligne (int[][] grille, int i) {
int t = 0;
for(int j = 0; j < 9; j++) {
t += grille[i][j];
}
return t;
}
/**
* la somme des nombres sur une zone 3×3 où se trouve (x, y)
* @param grille grille courante
* @param x numéro de la ligne
* @param y numéro de la colonne
* @return la somme des nombres
*/
public int calcul_bloc (int[][] grille, int x, int y) {
int i, j;
int v = x / 3 * 3;
int h = y / 3 * 3;
int t = 0;
for(i = v; i < v + 3; i++) {
for(j = h; j < h + 3; j++) {
t += grille[i][j];
}
}
return t;
}
/**
* Affichage de grille
* @param g la grille courante
*/
public void afficher (int[][] g) {
int i, j;
for(i = 0; i < 9; i++) {
for(j = 0; j < 9; j++) {
System.out.print("----");
}
System.out.println("-");
System.out.print("|");
for(j = 0; j < 9; j++) {
if (save[i][j] == 0) {
System.out.print((g[i][j] != 0 ? " " + g[i][j] + " " : " . ") + "|");
} else {
System.out.print("[" + g[i][j] + "]|");
}
}
System.out.println();
}
for(j = 0; j < 9; j++) {
System.out.print("----");
}
System.out.println("-\n");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment