/* Auteur: Nicolas JANEY          */
/* nicolas.janey@univ-fcomte.fr   */
/* Mars 2006                      */

public class CarreMagiqueEnConsole {

  /* Creation d'une chaine de caracteres                  */
  /* representant un nombre entier complemente par        */
  /* des espaces pour obtenir une longueur totale fixee   */

  public static String format(int n,int l) {
    String s = ""+n;
    int i = s.length();
    for ( ; i < l ; i++ )
      s = " "+s;
    return(s);
  }

  /* Affichage d'une matrice d'entiers formatee           */
  /* en lignes et en colonnes                             */

  public static void affichageMatrice(int [][] m) {
    for ( int i = 0 ; i < m.length ; i++ ) {
      for ( int j = 0 ; j < m[i].length ; j++ )
        Console.out.print(format(m[i][j],5));
      Console.out.println(); }
  }

  /* Creation d'une matrice d'entiers tires au sort entre */
  /* 0 et une valeur limite pour un nombre arbitraire     */
  /* de lignes et de colonnes                             */

  public static int [][] matriceAuHasard(int lignes,int colonnes,int max) {
    int [][] m = new int[lignes][colonnes];
    for ( int i = 0 ; i < lignes ; i++ )
      for ( int j = 0 ; j < colonnes ; j++ )
        m[i][j] =(int) (Math.random()*(max+1));
    return(m);
  }

  /* Calcul de la somme des valeurs d'une ligne           */
  /* d'une matrice d'entiers                              */

  public static int sommeLigneMatrice(int [][] m,int nb) {
    int cumul = 0;
    for ( int i = 0 ; i < m.length ; i++ )
      cumul += m[nb][i];
    return(cumul);
  }

  /* Calcul de la somme des valeurs d'une colonne         */
  /* d'une matrice d'entiers                              */

  public static int sommeColonneMatrice(int [][] m,int nb) {
    int cumul = 0;
    for ( int i = 0 ; i < m.length ; i++ )
      cumul += m[i][nb];
    return(cumul);
  }

  /* Calcul de la somme des valeurs d'une diagonale       */
  /* montante ou descendante d'une matrice d'entiers      */

  public static int sommeDiagonaleMatrice(int [][] m,int nb,boolean sens) {
    int cumul = 0;
    for ( int i = 0 ; i < m.length ; i++ )
      cumul += m[(i+nb)%m.length][(sens) ? i : m.length-1-i];
    return(cumul);
  }

  /* Test de la presence de tous les entiers de 1 a NxN   */
  /* dans une matrice carree d'entiers de taille N        */

  public static boolean testEnsembleNombresMatrice(int [][] t) {
    int i;
    int nb = t.length*t.length;
    boolean [] b = new boolean[nb];
    int v;
    boolean res = true;
    for ( i = 0 ; i < nb ; i++ )
      b[i] = false;
    i = 0;
    while ( res && ( i < nb ) ) {
      v = t[i/t.length][i%t.length]-1;
      if ( ( v < 0 ) || ( v >= nb ) )
        res = false;
        else
        if ( b[v] )
          res = false;
          else
          b[v] = true;
      i++; }
    return(res);
  }

  /* Realisation de tous les criteres de test d'un carre  */
  /* magique sur une matrice particuliere                 */

  public static void test(int [][] mat) {
    Console.out.println("Matrice testee");
    affichageMatrice(mat);
    Console.out.println("Sommes des lignes");
    for ( int i = 0 ; i < mat.length ; i++ ) {
      int s = sommeLigneMatrice(mat,i);
      Console.out.print(s+" "); }
    Console.out.println();
    Console.out.println("Sommes des colonnes");
    for ( int i = 0 ; i < mat.length ; i++ ) {
      int s = sommeColonneMatrice(mat,i);
      Console.out.print(s+" "); }
    Console.out.println();
    Console.out.println("Sommes des diagonales descendantes");
    for ( int i = 0 ; i < mat.length ; i++ ) {
      int s = sommeDiagonaleMatrice(mat,i,true);
      Console.out.print(s+" "); }
    Console.out.println();
    Console.out.println("Sommes des diagonales montantes");
    for ( int i = 0 ; i < mat.length ; i++ ) {
      int s = sommeDiagonaleMatrice(mat,i,false);
      Console.out.print(s+" "); }
    Console.out.println();
    Console.out.println(testEnsembleNombresMatrice(mat));
    Console.out.println();
  }

  /* Fonction principale                                  */

  public static void main(String [] args) {
    Console.setTitle("CarreMagique");
    { int [][] mat = matriceAuHasard(3,3,100);
      test(mat); }
    { int [][] mat = { {  7,12, 1,14 },
                       {  2,13, 8,11 },
                       { 16, 3,10, 5 },
                       {  9, 6,15, 4 } };
      test(mat); }
    { int [][] mat = { {  1,15,24, 8,17 },
                       { 23, 7,16, 5,14 },
                       { 20, 4,13,22, 6 },
                       { 12,21,10,19, 3 },
                       {  9,18, 2,11,25 } };
      test(mat); }
  }
}