/* -*-coding: utf-8; -*- */
// le commentaire ci-dessus valide le codage de caractère utf-8 (défaut sous linux-ubuntu)
// ce qui permet d'utiliser les caractères accentués. ATTENTION : ne fonctionne
// probablement pas par défaut sous d'autres systèmes d'exploitation. 

#include <stdio.h>
#include <string.h>

// ##########
// utilitaire utilisé dans plusieurs exos
#define TAILLE 50
SaisirChaine(char *msg) {
    fgets(msg,TAILLE,stdin);
    if (msg[strlen(msg)-1]=='\n')
      msg[strlen(msg)-1]=0;
}

// ##########
//exo1
void MonPrintf(char *t);

void exo1() {
  char msg[TAILLE];
  printf("Entrez une chaîne de caractères ");
  SaisirChaine(msg);
  MonPrintf(msg);

}

void MonPrintf(char *t) {
  int i = 0;
  
  while (t[i] != '\0'){
    printf("%c",t[i]);
    i++;
  }
  printf("\n");
}
	
// ##########
// exo 2
void EnMajuscules(char *t);

void exo2() {
  char msg[TAILLE];
  printf("Entrez une chaîne de caractères ");
  SaisirChaine(msg);
  EnMajuscules(msg);
  printf("%s\n",msg);
}

void EnMajuscules(char *t) {
  char c;
  int i = 0;
  
  c = t[i];
  
  while (c != '\0'){
    
    if (c >= 'a' && c <= 'z')
      c = c - 'a' + 'A';
    t[i] = c;
    
    i++;
    c = t[i];
  }
}

// ##########
//exo3

int EstPalindrome(char * t);

void exo3() {
  char msg[TAILLE];
  
  printf("Entrez une chaîne de caractères ");
  SaisirChaine(msg);
  if (EstPalindrome(msg))
    printf("\n%s est un palindrome\n",msg);
  else
    printf("\n%s N'est PAS un palindrome\n",msg);
}

int EstPalindrome(char *t) {
  int i,j;
  
  i=0; // indice 1ere lettre
  j = strlen(t)-1; // indice derniere lettre
  
  while (i<j) {
    /* est ce que les caractères i et strlen(mot)-i-1 sont égaux ? */
    if (t[i] != t[j])
      return 0; // non, FAUX
    // oui, au suivant, en passant les espaces
    while (t[i++]==' ');
    while (t[j--]==' ');
  }
  return 1; // ici tout a été vérifié
}

// ##########
//exo4
int syracuse(int nb) {
  if (nb%2==0) // pair
    return nb/2;
  else
    return 3*nb+1;
}

int conjecture(int n, int debut) {
  // attention, n doit être positif
  int i;
  for (i=0; i<n; i++) {
    debut=syracuse(debut);
  }
  return debut;
}

void exo4() {
  int nb, iter;
  printf("entrez votre nombre de départ, et le nombre d'itération :\n");
  scanf("%d %d", &nb, &iter);
  printf("resultat = %d\n", conjecture(iter,nb));
}

// ##########
//exo5
int VerifierMotif(char *ch, char *motif) {
  // renvoie vrai si le motif est au début de chaine
  int i; // indice dans ch et dans motif
  i=0;
  // tester correspondance sans déborder 
  // ni de la chaine, ni du motif
  while (ch[i] !=0 && motif[i]!=0) {
    // si ce n'est pas un joker, et pas correspondance
    if (motif[i] != '?' && motif[i] != ch[i]) {
      return 0; // erreur, quitter tour de suite
    }
    // sinon passer au suivant
    i++;
  }
  // est-on arrivé au bout du motif ? si oui succès, sinon pb
  return (motif[i]==0);
} // VerifierMotif

int teste(char *chaine, char *motif) {
  int i;
  int trouve=0; //pas encore trouvé
  // cherche correspondance à chaque position possible de la chaine
  // ATTENTION: la conversion en (int) est nécessaire sous gcc
  for (i=0; i < (int)(strlen(chaine)-strlen(motif)+1); i++) {
    trouve=VerifierMotif(chaine+i,motif);
    if (trouve) // n'allons pas plus loin
      break;
    i++;
  }
  return trouve;
}
    
void exo5() {
  char msg[TAILLE];
  printf("Entrez une chaîne de caractères ");
  SaisirChaine(msg);
  char motif[TAILLE];
  printf("Entrez le motif régulier ");
  SaisirChaine(motif);
  
  if (teste(msg,motif)) 
    printf("Correspondance\n");
  else
    printf("Ne correspond pas\n");
}

// ##########
// main
int main() {
  /* exo1(); */
  /* exo2(); */
  /* exo3(); */
  /* exo4(); */
  exo5();
  return 0;
}

