Aller au contenu

Exercices initiaux

Consignes

  • Ne pas de faire aider par des IA ou genAI

Série 1

  1. Créer un programme Java qui permet de jouer à pile ou face, le programme lance une pièce au hasard et demande à l'utilisateur de saisir pile ou face au clavier. Le programme affiche le résultat et si l'utilisateur a gagné ou perdu.
  2. Créer un programme Java qui permet de jouer au jeu de "devine un nombre". Le programme génère un nombre aléatoire entre 1 et 20 (1 et 20 sont inclus) et demande à l'utilisateur de deviner ce nombre. Le programme affiche, pour chaque proposition de l'utilisateur, si le nombre est plus grand ou plus petit que le nombre choisi. Si l'utilisateur trouve le nombre, Le programme affiche le nombre d'essais qu'il lui a fallu pour trouver ce nombre.
  3. Écrire un programme Java qui permet d'afficher l'inverse d'une chaîne de caractères. Par exemple, si l'utilisateur saisit "Bonjour", le programme affiche "ruojnoB". Ne pas utiliser de méthodes de la classe String (comme reverse). La chaîne en entrée est passé en argument de la ligne de commande.
  4. Écrire un programme Java qui permet de dire si une chaîne de caractères est un palindrome. Un palindrome est un mot qui se lit de la même façon de gauche à droite et de droite à gauche. Par exemple, "radar" est un palindrome. Ne pas utiliser de méthode de la classe String. Faire l'exercice avec et sans la méthode equals. La chaîne en entrée est passé en argument de la ligne de commande.
    • Exemples:
      • Si on passe "radar" en entrée, le programme affiche "Palindrome"
      • Si on passe "bonjour" en entrée, le programme affiche "Pas un palindrome"
  5. Écrire un programme Java qui permet de saisir un nombre entier et de calculer la somme de ses chiffres. Le programme affiche la somme des chiffres ainsi que le détail du calcul. Le nombre en entrée est passé en argument de la ligne de commande.
    • Exemples :
      • Si on passe 123 en entrée, le programme affiche "6 (1 + 2 + 3 = 6)"
      • Si on passe 1234 en entrée, le programme affiche "10 (1 + 2 + 3 + 4 = 10)"
  6. Créer un programme Java qui permet de saisir un entier et de vérifier si cet entier est un nombre premier. Le nombre en entrée est récupéré via le Scanner. Rappel : un nombre premier est un nombre qui est divisible par exactement deux entiers distincts (qui sont 1 et le nombre-même). 0 et 1 ne sont pas des nombres premiers par définition (1 n'est pas divisible par deux nombres distincts).
Guess the number
///usr/bin/env jbang "$0" "$@" ; exit $?

import static java.lang.System.*;

import java.util.Scanner;
import java.util.random.RandomGenerator;

public class GuessNumber {

  public static void main(String... args) {
    // var permet de faire du typage implicite
    var randomGenerator = RandomGenerator.getDefault();
    int numberToGuess = randomGenerator.nextInt(1, 21);

    Scanner scanner = new Scanner(System.in);

    int proposition = scanner.nextInt();
    while (proposition != numberToGuess) {
      if (proposition < numberToGuess) {
        System.out.println("Plus");
      } else {
        System.out.println("Moins");
      }
      proposition = scanner.nextInt();
    }
    System.out.println("Gagné");
    scanner.close();
  }
}
Heads or Tails
///usr/bin/env jbang "$0" "$@" ; exit $?

import static java.lang.System.*;

import java.util.Scanner;
import java.util.random.RandomGenerator;

public class HeadsOrTails {

  public static void main(String... args) {

    var randomGenerator = RandomGenerator.getDefault();
    boolean isHeads = randomGenerator.nextBoolean();
    // Opérateur ternaire ? : (ternainre: trois opérandes)
    String side = isHeads ? "pile" : "face";
    // équivalent à ça
    if (isHeads) {
      side = "pile";
    } else {
      side = "face";
    }

    var s = new Scanner(System.in);
    var answer = s.nextLine();
    s.close();

    System.out.println(side);

    if (side.equals(answer)) {
      System.out.println("Gagné");
    } else {
      System.out.println("perdu");
    }
  }
}
Reverse a string
///usr/bin/env jbang "$0" "$@" ; exit $?

import static java.lang.System.*;

public class ReverseManual {

  public static void main(String... args) {
    if (args.length == 0) {
      System.err.println("Usage: ReverseManual inputString");
      exit(1);
    }

    // Récupération de l'argument passé en ligne de commande
    String input = args[0];
    String output = "";
    // StringBuffer propose la méthode setCharAt non disponible dans String
    StringBuffer reversedStringBuffer = new StringBuffer();
    reversedStringBuffer.setLength(input.length());

    for (int i = 0; i < input.length(); i++) {
      output = input.charAt(i) + output;
      reversedStringBuffer.setCharAt(input.length() - i - 1, input.charAt(i));
    }

    System.out.println("solution 1: " + output);
    System.out.println("solution 2: " + reversedStringBuffer);
  }
}
Reverse many strings
///usr/bin/env jbang "$0" "$@" ; exit $?

import static java.lang.System.*;

public class ReverseManualMany {

  public static void main(String... args) {
    if (args.length == 0) {
      System.err.println("Usage: ReverseManual inputString");
      exit(1);
    }

    for (String input : args) {
      String output = "";
      for (int i = 0; i < input.length(); i++) {
        output = input.charAt(i) + output;
      }

      System.out.println(output);
    }
  }
}
Palindrome
///usr/bin/env jbang "$0" "$@" ; exit $?

import static java.lang.System.*;

public class Palindrome {

  public static boolean isPalindromeWithEquals(String input) {
    String reversed = "";
    for (int i = 0; i < input.length(); i++) {
      reversed = input.charAt(i) + reversed;
    }
    return input.equalsIgnoreCase(reversed);
  }

  public static boolean isPalindromeWithoutEquals(String input) {
    for (int i = 0; i < input.length() / 2; i++) {
      if (input.charAt(i) != input.charAt(input.length() - 1 - i)) {
        return false;
      }
    }
    return true;
  }

  public static void main(String... args) {
    if (args.length == 0) {
      System.err.println("Usage: Palindrome inputString");
      exit(1);
    }
    System.out.println("Is palindrome with equals");
    System.out.println(isPalindromeWithEquals(args[0]) ? "Palindrome" : "Pas un Palindrome");
    System.out.println("Is palindrome without equals: ");
    System.out.println(isPalindromeWithoutEquals(args[0]) ? "Palindrome" : "Pas un Palindrome");
  }
}
Count digits
///usr/bin/env jbang "$0" "$@" ; exit $?

import static java.lang.System.*;

public class CountDigits {

  public static void main(String... args) {
    if (args.length == 0) {
      System.err.println("Usage: CountDigits inputNumber");
      exit(1);
    }
    int input = Integer.parseInt(args[0]);
    String detail = " (";
    int sum = 0;
    // Pour ne pas afficher le + dans le détail du calcul du premier nombre
    boolean isFirst = true;
    while (input != 0) {
      int digit = input % 10;
      String prefix = isFirst ? "" : " + ";
      detail += prefix + digit;
      isFirst = false;
      input = input / 10;
      sum += digit;
    }
    detail += ")";

    System.out.println(sum + detail);
  }
}
Is prime ?
///usr/bin/env jbang "$0" "$@" ; exit $?

import static java.lang.System.*;

import java.util.Scanner;

public class IsPrime {

  public static void main(String... args) {
    System.out.println("Veuillez saisir un entier positif et on vous dira s'il est premier.");

    Scanner scanner = new Scanner(System.in);
    long input = scanner.nextLong();
    scanner.close();
    if (input < 0) {
      System.err.println("ce n'est pas un nombre positif");
      exit(1);
    } else if (input < 2) {
      System.out.println("ce n'est pas un nombre premier");
      exit(1);
    } else if (input == 2) {
      System.out.println("c'est un nombre premier");
      exit(0);
    }

    for (long i = 2; i < input / 2; i++) {
      if (input % i == 0) {
        System.out.println("Ce n'est pas un nombre premier");
        exit(1);
      }
    }
    System.out.println("C'est un nombre premier");
  }
}

Série 2

  1. Créer une application Java qui génère continuellement des nombres aléatoires entre 1 et 5 (inclus) et s'arrête dès que le nombre 3 est généré 5 fois. Avant de s'arrêter, le programme affiche la somme et la moyenne des nombres générés. Ne pas utiliser de tableaux.
  2. Créer une application Java qui affiche les 10 premiers termes de la suite de Fibonacci. La suite de Fibonacci est une suite de nombres dans laquelle chaque nombre est la somme des deux précédents. Les deux premiers termes de la suite sont 0 et 1. Par exemple, les 10 premiers termes de la suite de Fibonacci sont : 0, 1, 1, 2, 3, 5, 8, 13, 21, 34.
  3. Créer une application Java qui calcule le plus grand diviseur commun (PGCD) de deux entiers. Le PGCD de deux entiers est le plus grand entier qui divise les deux entiers sans reste. Par exemple, le PGCD de 12 et 18 est 6. Le programme affiche les pgcd des couples suivants: 12 et 18 (le pgcd est 6), 48 et 18 (le pgcd est 6), 56 et 42 (le pgcd est 14), 101 et 10 (le pgcd est 1), 100 et 25 (le pgcd est 25).
  4. Créer une application Java qui simule le déroulement d'un jeu d'action 1D. La carte du jeu est représentée par une chaine de caractères. Le joueur est représenté par un "J", les ennemis par des E, le potions par des P, les cases vides par . et la sortie par S. Le joueur se déplace de gauche à droite d'une case à chaque tour. Tout le reste est immobile (ennemis, potions et sortie). Chaque rencontre avec un ennemi fait perdre 1 point de vie et un tour et fait gagner 1 magolon (la monnaie locale). Chaque potion ramassée fait gagner 1 point de vie et fait perdre un tour. Le joueur commence avec 3 points de vie et 0 magolons. Le jeu s'arrête lorsque le joueur n'a plus de points de vie ou lorsqu'il a atteint une sortie.
    • Pour chaque carte donnée, le programme affiche le nombre de tours effectués pour atteindre la sortie ou mourir, le nombre de magolons gagnés, le nombre de points de vie restants et s'il a réussi ou échoué.
    • Par exemple, pour la carte suivante : "J..E..P..S", le programme affiche "Le joueur a réussi à atteindre la sortie en 11 tours avec 1 magolon et 3 points de vie restants".
    • Afficher le résultat du jeu pour les cartes suivantes : "J...S" (4 tour, 0 magolons, vivant), "J..E..P..S" (11 tours, 1 magolon, vivant), "J..EE.E..S" (9 tours, 0 magolons, mort), "J..E..P..E..P..S", "J..E..PP..EEE..P..E..S".
    • Afficher le résultat du jeu pour les cartes suivantes: "..J..S...EP", "E.PSJ..EPPP...S.EP", "SE.SPE.J..EPEE.EPEE.PEPE..S.PSP".
  5. Supposons qu'on ait deux cercles : un cercle de centre A et de rayon Ra, et un cercle de centre B et de rayon Rb. Les coordonnées de A sont notées (xa, ya) et les coordonnées de B sont notées (xb, yb). On souhaite écrire une fonction permettant de dire si les deux cercles entrent en collision. La distance entre les deux centres A et B est: sqrt((xb-xa)² + (yb-ya)²)
    • Donner la condition qui permet de savoir s’il y a collision (ou pas) entre les cercles.
    • Exprimer cette condition sans racine carrée.
    • Ecrire une fonction isCollision qui prend les informations de deux cercles en arguments et renvoie true s’il y a collision entre les deux cercles, sinon false.
    • Faire cet exercice en définissant une classe Circle et une méthode isCollision.
Solutions
ContinuousRandomStats
///usr/bin/env jbang "$0" "$@" ; exit $?

import static java.lang.System.*;

import java.util.random.RandomGenerator;

public class ContinuousRandomStats {

  public static void main(String... args) {
    RandomGenerator randomGenerator = RandomGenerator.getDefault();
    int foundCount = 0;
    int sum = 0;
    int generatedIntCount = 0;
    while (foundCount < 5) {
      int generatedInt = randomGenerator.nextInt(1, 6);
      if (generatedInt == 3) {
        foundCount += 1;
        System.out.println(String.format("Found 3 %d times", foundCount));
      }
      sum += generatedInt;
      generatedIntCount += 1;
    }
    int mean = sum / generatedIntCount;
    System.out.println(String.format("Sum: %d, count: %d, mean: %d", sum, generatedIntCount, mean));
  }
}
FibonacciInitial
///usr/bin/env jbang "$0" "$@" ; exit $?

import static java.lang.System.*;

import java.util.logging.Logger;

public class FibonacciInitial {

  public static void main(String... args) {
    Logger.getGlobal().info(String.format("F(0): %d", 0));
    Logger.getGlobal().info(String.format("F(1): %d", 1));
    int secondToLast = 0;
    int last = 1;
    for (int i = 2; i < 10; i++) {
      int current = secondToLast + last;
      Logger.getGlobal().info(String.format("F(%d): %d", i, current));
      secondToLast = last;
      last = current;
    }
  }
}
pgcd
///usr/bin/env jbang "$0" "$@" ; exit $?

import static java.lang.System.*;

public class pgcd {

  public static int computePgcd(int a, int b) {
    int min = a <= b ? a : b;
    int pgcd = 1;
    // On trouve le diviseur commun de 1 jusqu'a plus petit des deux arguments
    for (int i = 1; i <= min; i++) {
      // Si on trouve un nouveau diviseur plus grand (car i s'incrémente), on écrase
      // la variable pgcd
      if (a % i == 0 && b % i == 0) {
        System.out.println(String.format("Trouvé nouveau pgcd %d", i));
        pgcd = i;
      }
    }
    return pgcd;
  }

  public static int computePgcdFaster(int a, int b) {
    int min = a <= b ? a : b;
    // On démarre directement du min et on s'arrête dès qu'on trouve un diviseur
    // commun
    for (int i = min; i >= 1; i--) {
      if (a % i == 0 && b % i == 0) {
        System.out.println(String.format("pgcd trouvé %d", i));
        return i;
      }
    }
    return 1;
  }

  public static void main(String... args) {
    System.out.println(String.format("pgcd(3, 6)=%d", computePgcd(3, 6)));
    System.out.println(String.format("pgcd(77, 11)=%d", computePgcd(77, 11)));
    System.out.println(String.format("pgcd(31, 107)=%d", computePgcd(31, 107)));

    System.out.println("Faster");
    System.out.println(String.format("pgcd(3, 6)=%d", computePgcdFaster(3, 6)));
    System.out.println(String.format("pgcd(77, 11)=%d", computePgcdFaster(77, 11)));
    System.out.println(String.format("pgcd(31, 107)=%d", computePgcdFaster(31, 107)));
  }
}
adventure1d
///usr/bin/env jbang "$0" "$@" ; exit $?

// Un record est une class plus concise (syntaxe plus courte et simple)
record LevelResult(int hp, int magolon, int turnCount) {
  @Override
  public final String toString() {
    return String.format("Hero has %d hp, %d magolon. He %s the level after %d turns",
        this.hp, this.magolon, this.hp <= 0 ? "failed" : "succeeded", this.turnCount);
  }
}

public class adventure1d {
  // throw est une sorte de return alternatif pour les cas d'erreur (object
  // Exception)
  public static LevelResult playLevel(String level) throws Exception {
    int hp = 3;
    int turnCount = 0;
    int magolon = 0;
    // D'abord trouver l'indice du joueur dans la carte
    int playerInitialPosition = 0;
    for (; level.charAt(playerInitialPosition) != 'J'
        && playerInitialPosition < level.length(); playerInitialPosition++) {
    }
    // Vérifier que la position du joueur est au moins l'avant dernière case
    if (playerInitialPosition >= level.length() - 1) {
      Exception exception = new Exception("Position intiale du joueur invalide");
      throw exception;
    }
    System.out.format("Initiall player position %d\n", playerInitialPosition);
    // Dérouler le niveau
    for (int i = playerInitialPosition + 1; i < level.length(); i++) {
      turnCount += 1;
      char currentTile = level.charAt(i);
      if (currentTile == 'S') {
        break;
      } else if (currentTile == 'E') {
        turnCount += 1;
        hp -= 1;
        if (hp == 0) {
          break;
        }
        magolon += 1;
      } else if (currentTile == 'P') {
        turnCount += 1;
        hp += 1;
      } else if (currentTile != '.') {
        throw new Exception(String.format("Incorrect tile %c", currentTile));
      }
    }
    return new LevelResult(hp, magolon, turnCount);
  }

  public static void main(String... args) throws Exception {
    String[] firstLevels = {
        "J..S", "J..E..P..S", "J..EE.E..S", "J..E..P..E..P..S", "J..E..PP..EEE..P..E..S"
    };
    for (String level : firstLevels) {
      LevelResult levelResult = playLevel(level);
      System.out.format("Playing level '%s'. Result: %s\n", level, levelResult);
    }
    for (String level : new String[] {
        "..J..S...EP", "E.PSJ..EPPP...S.EP", "SE.SPE.J..EPEE.EPEE.PEPE..S.PSP"
    }) {
      LevelResult levelResult = playLevel(level);
      System.out.format("Playing level '%s'. Result: %s\n", level, levelResult);
    }

    for (String level : new String[] {
        "..J.J.S..", "JN", "..."
    }) {
      try {
        LevelResult levelResult = playLevel(level);
        System.out.format("Playing level '%s'. Result: %s\n", level, levelResult);
      } catch (Exception e) {
        System.out.format("Skipping incorrect level. Cause: %s\n", e.getMessage());
      }
    }
  }
}
CircleCollisionDetector
///usr/bin/env jbang "$0" "$@" ; exit $?

public class CircleCollisionDetector {
  public static void main(String[] args) {
    CircleCollisionDetector circleCollisionDetector = new CircleCollisionDetector();
    circleCollisionDetector.isColliding(0, 0, 10, 10, 0, 10);
  }

  /**
   * La distance entre les deux cercles est plus petite que la somme des rayons
   * 
   * @param xa
   * @param ya
   * @param ra
   * @param xb
   * @param yb
   * @param rb
   * @return
   */
  boolean isColliding(int xa, int ya, int ra, int xb, int yb, int rb) {
    return Math.pow(xb - xa, 2) + Math.pow(yb - ya, 2) < Math.pow(rb + ra, 2);
  }
}