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

// Exercice 1

int puissance(int a, int b)
{
  int res = 1;
  for (int i = 0 ; i < b ; i += 1) res *= a;
  return res;
}

int puissance_rec(int a, int b) // Adapter la fonction main1
{
  if (b == 0) return 1;
  return puissance_rec(a, b-1) * a;
}

int puissance_rapide(int a, int b) // Idem
{
  int res = 1;
  while (b != 0)
  {
    if (b % 2 == 1) res *= a;
    a *= a;
    b /= 2;
  }
  return res;
}

int puissance_rapide_rec(int a, int b) // Idem
{
  if (b == 0) return 1;
  if (b % 2 == 1) return a * puissance_rapide_rec(a * a, b / 2);
  return puissance_rapide_rec(a * a, b / 2);
}

int main1() // Un seul main par fichier, mais exercice par exercice on retire le nombre
{
  int a = 4;
  int b = 6;
  printf("%d ^ %d = %d\n", a, b, puissance(a, b));
  return 0;
}

// Exercice 2

int somme_chiffres(int n)
{
  int res = 0;
  if (n < 0) n = -n; // Gestion des négatifs quand même.
  while (n != 0)
  {
    res += n % 10;
    n /= 10;
  }
  return res;
}

int main2()
{
  int n = 423654;
  printf("Somme des chiffres de %d : %d.\n", n, somme_chiffres(n));
  return 0;
}

// Exercice 3

int somme_puissances(int n, int k)
{
  int res = 0;
  for (int i = 1 ; i <= n ; i += 1) res += puissance(i, k);
  return res;
}

int main3()
{
  int n = 10;
  int k = 3;
  printf("Somme des puissances %d-ièmes des entiers de 1 à %d : %d.\n", k, n, somme_puissances(n, k));
  return 0;
}

// Exercice 4

int nombre_chiffres(int n)
{
  int res = 1;
  while (n > 1)
  {
    res += 1;
    n /= 2;
  }
  return res;
}

int main4()
{
  int n = 127;
  printf("Nombre de chiffres de %d en binaire : %d.\n", n, nombre_chiffres(n));
  return 0;
}

// Exercice 5

void imprime_binaire(int n)
{
  if (n < 0)
  {
    printf("Erreur : n est négatif !");
    exit(-1); // Exemple avec la convention sur le retour global
  }
  printf("Écriture binaire de %d : ", n);
  if (n == 0)
  {
    printf("0\n");
    return;
  }
  int dpn = 1;
  while (2 * dpn <= n) dpn *= 2;
  while (dpn != 0)
  {
    if (n >= dpn)
    {
      printf("1");
      n -= dpn;
    }
    else
    {
      printf("0");
    }
    dpn /= 2;
  }
  printf("\n");
}

int main5()
{
  int n = 1000;
  imprime_binaire(n);
  return 0;
}

// Exercice 6

void deviner(int n, int k)
{
  int mini = 1;
  int maxi = n;
  while (mini <= maxi)
  {
    int essai = (mini + maxi) / 2;
    printf("Ordinateur : %d ?\n", essai);
    if (essai < k)
    {
      printf("Arbitre : C'est plus !\n");
      mini = essai + 1;
    }
    else if (essai > k)
    {
      printf("Arbitre : C'est moins !\n");
      maxi = essai - 1;
    }
    else
    {
      printf("Arbitre : C'est bon !\n");
      return;
    }
  }
  printf("On n'aurait jamais dû arriver là.\n");
}

int main6()
{
  int n = 19;
  int k = 12;
  deviner(n, k);
  return 0;
}

// Exercice 7

int pgcd(int a, int b)
{
  if (b == 0) return a;
  return pgcd(b, a % b);
}

int ppcm(int a, int b)
{
  if (a < 0) a = -a;
  if (b < 0) b = -b;
  if (a == 0 || b == 0)
  {
    printf("PPCM indéfini quand un des arguments est nul.\n");
    exit(-1);
  }
  return (a / pgcd(a, b))*b;
}

int main7()
{
  int a = 84;
  int b = 70;
  printf("Le plus petit commun multiple de %d et %d est %d.\n", a, b, ppcm(a, b));
  return 0;
}

// Exercice 8

bool premier(int n)
{
  if (n < 2) return false;
  int i = 2;
  while (i * i <= n)
  {
    if (n % i == 0) return false;
    i += 1;
  }
  return true;
}

int main8()
{
  int n = 354887341;
  if (premier(n)) printf("%d est premier.\n", n);
  else printf("%d n'est pas premier.\n", n);
  return 0;
}

// Fonction main

int main()
{
  int zero = main1(); // Ou un autre
  exit(zero);
}
