/* Auteur: Nicolas JANEY          */
/* nicolas.janey@univ-fcomte.fr   */
/* Fevrier 2005                   */

public class ReservationSalleEnConsole {

  /* Fonction de creation d'un planning                   */
  /* initialise avec des booleens aleatoires              */
  /* nbj : Nombre de jours du planning                    */
  /* nbc : Nombre de creneaux du planning                 */
  /* v : reel coefficient de chance qu'un creneau         */
  /* soit affecte                                         */
  /* Resultat fonction : Matrice de booleens              */

  public static boolean [][] creationPlanningAleatoire(int nbj,int nbc,double v) {
  /* Allocation de la matrice                             */
    boolean [][] p = new boolean[nbj][nbc];
  /* Pour tous les jours du planning a initialiser        */
    for ( int j = 0 ; j < nbj ; j++ )
  /* Pour tous les creneaux du planning a initialiser     */
      for ( int c = 0 ; c < nbc ; c++ )
  /* Initialisation avec un booleen aleatoire             */
        p[j][c] = (Math.random() < v);
  /* Resultat de la fonction                              */
    return(p);
  }

  /* Fonction de creation d'une matrice de reservations   */
  /* initialisee avec des valeurs aleatoires              */
  /* t : Nombre de reservations possibles de la matrice   */
  /* nb : Nombre de reservations effectives               */
  /* nbj : Nombre de jours de reservation                 */
  /* nbc : Nombre de creneaux de reservation              */
  /* Resultat fonction : Matrice d'entiers                */

  public static int [][] creationAleatoireReservations(int t,int nb,int nbj,int nbc) {
  /* Allocation de la matrice                             */
    int [][] r = new int[t][2];
  /* Pour toutes les reservations a initialiser           */
    for ( int i = 0 ; i < nb ; i++ ) {
  /* Initialisation d'une reservation                     */
      r[i][0] =(int) (Math.random()*nbj);
      r[i][1] =(int) (Math.random()*nbc); }
  /* Pour toutes les reservations restantes possibles     */
  /* dans r                                               */
    for ( int i = nb ; i < t ; i++ ) {
  /* Initialisation d'une reservation a libre             */
      r[i][0] = -1; }
  /* Resultat de la fonction                              */
    return(r);
  }

  /* Fonction d'affichage d'un planning                   */
  /* p : Planning a afficher                              */

  public static void affichagePlanning(boolean [][] p) {
  /* Pour tous les jours du planning                      */
    for ( int j = 0 ; j < p.length ; j++ ) {
  /* Pour tous les creneaux du jour courant               */
      for ( int c = 0 ; c < p[j].length ; c++ )
  /* Si le creneau courant du jour courant est libre      */
        if ( p[j][c] )
  /* On affiche sans retour a la ligne le caractere V     */
          Console.out.print(" V");
          else
  /* Sinon, on affiche F sans retour a la ligne           */
          Console.out.print(" F");
  /* On va a la ligne quand les creaneaux d'un jour       */
  /* sont tous affiches                                   */
      Console.out.println(); }
  }

  /* Fonction d'affichage d'une matrice de demandes       */
  /* de reservations                                      */
  /* r : Tableau de reservations a afficher               */

  public static void affichageDemandesReservation(int [][] r) {
  /* Definition et initialisation a 0 d'un indice         */
  /* de parcours de la matrice des reservations           */
    int i = 0;
  /* Tant que tous le tableau des reservations n'est pas  */
  /* parcouru et que la reservation courante est valide   */
    while ( ( i < r.length ) && ( r[i][0] != -1 ) ) {
  /* Affichage de la demande de reservation courante      */
      Console.out.println(r[i][0]+" "+r[i][1]);
  /* L'indice de parcours du tableau des demandes         */
  /* de reservation est incremente de 1                   */
      i++; }
  }

  /* Fonction de calcul du pourcentage de reservation     */
  /* de l'ensemble des creneaux d'un planning             */
  /* p : Planning a traiter                               */
  /* Resultat fonction : Reel (pourcentage de creneaux    */
  /* reserves)                                            */

  public static double pourcentageReservation(boolean [][] p) {
  /* Definition et initialisation a 0 d'un compteur       */
    int cpt = 0;
  /* Pour tous les jours du planning                      */
    for ( int j = 0 ; j < p.length ; j++ ) {
  /* Pour tous les creneaux du jour courant               */
      for ( int c = 0 ; c < p[j].length ; c++ )
  /* Si le creneau courant du jour courant est reserve    */
        if ( p[j][c] )
  /* Le compteur est incremente de 1                      */
          cpt++; }
  /* Resultat fonction : Compteur/nombre de creneaux      */
  /* total du planning * 100                              */
    return((double) cpt/p.length/p[0].length*100.0);
  }

  /* Fonction de determination si tous les creneaux       */
  /* d'un jour d'un planning sont libres                  */
  /* p : Planning a traiter                               */
  /* j : Jour a tester                                    */
  /* Resultat fonction : Booleen (vrai si tous            */
  /* sont libres, faux sinon)                             */

  public static boolean estLibre(boolean [][] p,int j) {
  /* Definition et initialisation a 0 d'un indice         */
  /* de parcours des creneaux du jour j du planning p     */
    int c = 0;
  /* Pour tous les creneaux du jour j                     */
    while ( c < p[j].length ) {
  /* Si le creneau c du jour j est reserve                */
      if ( p[j][c] )
  /* La fonction est terminee avec pour resultat faux     */
        return(false);
  /* l'indice de parcours des creneaux est incremente     */
  /* de 1                                                 */
      c++; }
  /* Resultat fonction : Si la fonction ne s'est pas      */
  /* terminee avec pour resultat faux, le resultat        */
  /* est vrai                                             */
    return(true);
  }

  /* Fonction de reservation dans un planning             */
  /* des demandes de reservation stockees dans un tableau */
  /* de reservations                                      */
  /* p : Planning a traiter                               */
  /* r : Tableau des reservations a traiter               */
  /* Resultat fonction : Entier (nombre de reservations   */
  /* non effectuees car non possibles                     */

  public static int reservation(boolean [][] p,int [][] r) {
  /* Definition et initialisation a 0 d'un compteur       */
  /* de reservations non effectuees                       */
    int cpt = 0;
  /* Definition et initialisation a 0 d'un indice         */
  /* de parcours de la matrice des reservations           */
    int i = 0;
  /* Tant que tous le tableau des reservations n'est pas  */
  /* parcouru et que la reservation courante est valide   */
    while ( ( i < r.length ) && ( r[i][0] != -1 ) ) {
  /* Si le creneau correspondant a la demande             */
  /* de reservation courante est deja reserve             */
      if ( p[r[i][0]][r[i][1]] )
  /* Le compteur de reservation est incremente de 1       */
        cpt++;
        else
  /* Sinon, la reservation est effectuee                  */
        p[r[i][0]][r[i][1]] = true;
  /* L'indice de parcours du tableau des demandes         */
  /* de reservation est incremente de 1                   */
      i++; }
  /* Resultat fonction : Entier (Nombre de reservations   */
  /* non effectuees                                       */
    return(cpt);
  }

  /* Fonction principale                                  */

  public static void main(String [] args) {
    Console.setTitle("ReservationSalle");
  /* Lecture au clavier du nombre de jours du planning    */
    Console.out.print("Nombre de jours             : ");
    int nbj = Integer.valueOf(Console.in.readLine()).intValue();
  /* Lecture au clavier du nombre de creneaux par jour    */
    Console.out.print("Nombre de creneaux par jour : ");
    int nbc = Integer.valueOf(Console.in.readLine()).intValue();
  /* Lecture au clavier du facteur de reservation         */
    Console.out.print("Facteur de reservation      : ");
    double f = Double.valueOf(Console.in.readLine()).doubleValue();
  /* Creation d'un tableau de n entiers aleatoires        */
    boolean [][] p = creationPlanningAleatoire(nbj,nbc,f);
  /* Affichage du planning                                */
    Console.out.println("Le planning initial est :");
    affichagePlanning(p);
  /* Calcul et affichage du pourcentage de reservation    */
    Console.out.println("Le pourcentage de reservation est : "+pourcentageReservation(p));
  /* Lecture au clavier du jour a tester                  */
    Console.out.print("Jour a tester       : ");
    int j = Integer.valueOf(Console.in.readLine()).intValue();
  /* Calcul et affichage de la diponibilte entiere        */
  /* d'un jour                                            */
    Console.out.println("Le jour "+j+" est libre : "+estLibre(p,j));
  /* Lecture au clavier de la taille du tableau           */
  /* des reservations                                     */
    Console.out.print("Taille du tableau       : ");
    int t = Integer.valueOf(Console.in.readLine()).intValue();
  /* Lecture au clavier du nombre de reservations         */
    Console.out.print("Nombre de reservations  : ");
    int nb = Integer.valueOf(Console.in.readLine()).intValue();
    int [][] re = creationAleatoireReservations(t,nb,nbj,nbc);
  /* Affichage de l'ensemble des demandes de reservation  */
    affichageDemandesReservation(re);
  /* Reservation et affichage du resultat                 */
    Console.out.println("Le nombre de reservations non effectuees est : "+reservation(p,re));
  /* Affichage du planning apres reservations             */
    Console.out.println("Le planning apres reservation est :");
    affichagePlanning(p);
  }
}