#include <stdio.h>
#include <stdlib.h>

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//  REPONSE A LA QUESTION 9 SOUS FORME DE COMMENTAIRE
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//
//
//
//
//
//


//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//  DEFINITIONS
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// En cas d'erreur sur le nombre d'arguments
#define ERREUR_NBARGS 1

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// TYPES
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
typedef char *tmot; // Chaîne de caractères
typedef unsigned char uchar; // Entier naturel pour les adresses
typedef unsigned int uint; // Entier naturel pour les indices
typedef unsigned int *tperm; // En 0: longueur de la permutation

typedef struct tcell {  
  uint pos; // position d'une lettre d'un mot (1 à longueur(mot))
  struct tcell *suiv; // Pointeur sur la cellule suivante
} tcell;

typedef tcell *tliste; // Liste chaînée de cellules

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// VARIABLES GLOBALES 
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

tliste Casiers[26]; // Un casier par lettre de l'alphabet A = 0

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// FONCTIONS 
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

///////////////////////////////////////////////////////////////
// À COMPLÉTER - À COMPLÉTER - À COMPLÉTER - À COMPLÉTER 
// Renvoie la longueur du <mot> (chaine qui finit par '\0')
///////////////////////////////////////////////////////////////
uint len(tmot mot){



}

///////////////////////////////////////////////////////////////
// Convertit un mot en majuscules (sur place)
///////////////////////////////////////////////////////////////
tmot Majuscules(tmot mot){
  for (tmot p = mot; *p != '\0'; p++)
    if ((*p >= 'a') && (*p <= 'z'))
      *p = *p - 'a' + 'A';
  return mot;
}

//////////////////////////////////////////////////////////////
// À COMPLÉTER - À COMPLÉTER - À COMPLÉTER - À COMPLÉTER 
// Décide si deux chaînes de caractères sont égales
///////////////////////////////////////////////////////////////
int SontEgaux(tmot u, tmot v){



}

///////////////////////////////////////////////////////////////
// Initialise les 26 casiers à la liste vide (NULL)
///////////////////////////////////////////////////////////////
void InitCasiers(void){
  for (int i = 0; i < 26; i++) {
    Casiers[i] = NULL;
  }
}

///////////////////////////////////////////////////////////////
// À COMPLÉTER - À COMPLÉTER - À COMPLÉTER - À COMPLÉTER 
// Crée une cellule pour rajouter une position en tête de liste
///////////////////////////////////////////////////////////////
void Empiler(tliste *liste, uint pos){



}

///////////////////////////////////////////////////////////////
// Affiche la permutation perm codée par le tableau de ses
// images perm(i). N'affiche pas la valeur en position 0
// qui contient la longueur de la permutation.
///////////////////////////////////////////////////////////////
void AfficherPerm(tperm perm, char *nom_perm){
  uint n = perm[0];
  if (len(nom_perm) > 0)
    printf("%s = [", nom_perm);  
  else
    printf("[");    
  int i = 1;
  for (i = 1; i < n; i++)
    printf("%hu, ", perm[i]);
  printf("%hu", perm[i]);  
  printf("]\n");
}

///////////////////////////////////////////////////////////////
// À COMPLÉTER - À COMPLÉTER - À COMPLÉTER - À COMPLÉTER 
// Renvoie la permutation inverse de sigma.
///////////////////////////////////////////////////////////////
tperm Inverser(tperm perm){




}

///////////////////////////////////////////////////////////////
// À COMPLÉTER - À COMPLÉTER - À COMPLÉTER - À COMPLÉTER 
// Renvoie le produit des permutation sigma1 o sigma2.
///////////////////////////////////////////////////////////////
tperm Composer(tperm perm1, tperm perm2){




}

///////////////////////////////////////////////////////////////
// À COMPLÉTER - À COMPLÉTER - À COMPLÉTER - À COMPLÉTER
// Vide les casiers de leurs valeurs dans l'ordre alphabétique
// et les range au fur et à mesure dans une permutation.
// On rappelle que cette permutation est l'*inverse* de
// la permutation sigma qui "trie" le mot qui a servi à la 
// répartition des indices de ses lettres.
///////////////////////////////////////////////////////////////
tperm ViderCasiers(uint n){




}

///////////////////////////////////////////////////////////////
// Fonction d'adressage correspondant au rang d'une lettre
// dans l'aphabet latin: A -> 0, B -> 1, ..., Z -> 25
///////////////////////////////////////////////////////////////
uchar Adresse(char u){
  return u - 'A';
}

///////////////////////////////////////////////////////////////
// À COMPLÉTER - À COMPLÉTER - À COMPLÉTER - À COMPLÉTER 
// Range la position de chaque lettre de mot (de 1 à n := |mot|)
// dans les casiers avec la fonction d'adressage ci-dessus.
// Renvoie la permutation inverse amgis de la permutation sigma
// qui trie ce mot, i.e telle que sigma(mot) = mot_trie qui est
// récupéré grâce au passage par adresse.
///////////////////////////////////////////////////////////////
tperm TriAlpha(tmot mot, tmot *mot_trie){




}


///////////////////////////////////////////////////////////////
// À COMPLÉTER - À COMPLÉTER - À COMPLÉTER - À COMPLÉTER 
// Décide si deux mots u et v sont des anagrammes l'un de 
// l'autre. Le cas échéant, renvoie la permutation σ telle 
// que σ(u) = v sinon renvoie NULL.
///////////////////////////////////////////////////////////////
tperm SontAnagrammes(tmot u, tmot v){



}

int main(int argc, char *argv[]){

  // VÉRIFIE LE NOMBRE DE PARAMÈTRES 
  if ((argc < 3) || (argc > 4)) {
    printf("Syntaxe %s: mot1 mot2\n",argv[0]);
    return ERREUR_NBARGS;
  }

  // INITIALISE LES CASIERS
  InitCasiers();

  // CONVERTIT LES DEUX MOTS EN MAJUSCULES  
  tmot u = Majuscules(argv[1]);
  tmot v = Majuscules(argv[2]);

  // VÉRIFIE SI LES MOTS u ET v SONT DES ANAGRAMMES ET
  // LE CAS ÉCHÉANT, AFFICHE σ TELLE QUE σ(u) = v.
  tperm sigma = NULL;
  if ((sigma = SontAnagrammes(u, v)) != NULL){
    printf("σ(%s) = %s où ", u, v);
    AfficherPerm(sigma,"σ");
    free(sigma);
  }
  else
    printf("%s et %s ne sont pas des anagrammes\n", u,v);
  return 0; 
}
