Skip to content

Exercices série 3

Consignes

  • Ne pas de faire aider par des IA ou genAI

Exercice 1

  • Créer une fonction qui prend un tableau d’entiers “int[] numbers” et affiche la plus grande valeur et la plus petite valeur (Il faut calculer vous-même le max et le min)
  • Générer un tableau de 10 entier aléatoires et afficher le max et le min
  • Générer un tableau de 10 entiers saisis au clavier et afficher le max et le min

  • 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 un algorithme (très simple) permettant de dire si les deux cercles se rentrent dedans. 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 isCollision comme une méthode de cette classe
Random min and max
///usr/bin/env jbang --enable-preview "$0" "$@" ; exit $?

import java.util.random.RandomGenerator;
import static java.lang.System.*;

public class RandomMinMax {

  public static void printMinMax(int[] numbers) {
    if (numbers.length == 0) {
      return;
    }

    int min = numbers[0];
    int max = numbers[0];

    for (int number : numbers) {
      min = number < min ? number : min;
      max = number > max ? number : max;
    }
    System.out.println(STR."min: \{ min }, max: \{ max }");
  }

  public static void main(String... args) {
    RandomGenerator generator = RandomGenerator.getDefault();
    int[] numbers = new int[10];
    for (int i = 0; i < numbers.length; i++) {
      numbers[i] = generator.nextInt();
      System.out.print(STR."\{numbers[i]}, ");
    }
    System.out.println();
    printMinMax(numbers);
  }
}
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);
  }
}

Exercice 2

  • On souhaite modéliser une collection de consoles et jeux rétro. Les consoles (classe VideoGameConsole) et les jeux rétro (classe VideoGame) sont des appareils de divertissement ayant les propriétés: name, releaseYear en commun. Les consoles ont en plus la propriété: companyName (la société qui l'a créé). Les jeux vidéos ont comme propriété supplémentaire l'éditeur du jeu (celui qui le distribue) ainsi que son développeur. On aimerait aussi savoir s'il est indépendant ou pas.
  • Définir les classes nécessaires.
  • Chaque jeu vidéo tient une liste des consoles compatibles (pour les jeux cross-platform) via la propriété: platforms.
  • VideoGameConsole contient en plus la propriété: companyName de type string.
  • Compléter la définition des classes et instancier les jeux et consoles suivantes:

    • Console: name: My first 16 bit Console, releaseYear: 1987, companyName: SEGA
    • Console: name: Another 16 bit console, releaseYear: 1991, companyName: Nintendo
    • Console: name: Awesome 3D console, releaseYear: 1996, companyName: Sony
    • Console: name: 3D console with weird joystick, releaseYear: 1997, companyName: Nintendo
    • Jeu: name: Alex Kidd, releaseYear: 1988, editor: SEGA
    • Jeu: name: Sonic, releaseYear: 1990, editor: SEGA
    • Jeu: name: Mario RPG, releaseYear: 1996, editor: Nintendo
    • Jeu: name: Final Fantasy 6, releaseYear: 1994, editor: Square
  • En utilisant les streams:

    • Afficher les jeux sortis à partir de l'année 1990 triés par ordre croissant de l'année.
    • Afficher le nom des consoles de la compagnie SEGA.
    • Afficher le nom des consoles dont le nom contient le mot 16 bits.
    • Le nom du premier jeu sorti
    • Trouver le nombre de jeux de chaque éditeur en calculant dictionnaire dont la clé est l'éditeur ou son nom et en valeur le nombre de jeux
    • Pour chaque éditeur, l'année de sortie du premier jeu en calculant dictionnaire dont la clé est l'éditeur ou son nom et en valeur une année
Corrigé
///usr/bin/env jbang "$0" "$@" ; exit $?

//DEPS com.google.guava:guava:33.1.0-jre

import java.util.AbstractMap;
import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Collectors;

import com.google.common.base.Joiner;

abstract class EntertainmentDevice {
  private String name;
  private int releaseYear;

  public EntertainmentDevice(String name, int releaseYear) {
    this.name = name;
    this.releaseYear = releaseYear;
  }

  // propriété calculée
  public boolean isAfter2000() {
    return this.getReleaseYear() >= 2000;
  }

  public boolean isAfter1990() {
    return this.getReleaseYear() >= 1990;
  }

  // proriété avec backieng field (le backing field est name)
  public String getName() {
    return name;
  }

  // proriété avec backieng field (le backing field est name)
  public void setName(String name) {
    this.name = name;
  }

  public int getReleaseYear() {
    return releaseYear;
  }

  public void setReleaseYear(int releaseYear) {
    this.releaseYear = releaseYear;
  }
}

class VideoGameConsole extends EntertainmentDevice {
  private String companyName;

  public VideoGameConsole(String name, int releaseYear, String companyName) {
    super(name, releaseYear);
    this.companyName = companyName;
  }

  public String getCompanyName() {
    return companyName;
  }

  public void setCompanyName(String companyName) {
    this.companyName = companyName;
  }
}

class VideoGame extends EntertainmentDevice {
  private String publisher;

  public VideoGame(String name, int releaseYear, String publisher) {
    super(name, releaseYear);
    this.publisher = publisher;
  }

  public String getPublisher() {
    return publisher;
  }

  public void setPublisher(String publisher) {
    this.publisher = publisher;
  }

  @Override
  public String toString() {
    return "VideoGame [publisher=" + publisher + ", getName()=" + getName() + ", getReleaseYear()=" + getReleaseYear()
        + "]";
  }

}

public class RetroCollectionExercise {

  public static void main(String... args) {
    System.out.println("Retro game collection exercise");
    var consoles = List.of(
        new VideoGameConsole("My first 16 bits Console", 1987, "SEGA"),
        new VideoGameConsole("Another 16 bits console", 1991, "Nintendo"),
        new VideoGameConsole("Awesome 3D console", 1996, "Sony"),
        new VideoGameConsole("3D console with weird joystick", 1997, "Nintendo"));

    var games = List.of(
        new VideoGame("Alex Kidd", 1988, "SEGA"),
        new VideoGame("Starcraft 2", 1988, "BLIZZARD"),
        new VideoGame("Sonic", 1990, "SEGA"),
        new VideoGame("Mario RPG", 1996, "Nintendo"),
        new VideoGame("Final Fantasy 6", 1994, "Square"));

    var gamesAfter1990 = games.stream()
        .filter((game) -> game.getReleaseYear() >= 1990)
        .sorted(Comparator.comparingInt((game) -> game.getReleaseYear()))
        .toList();

    var gamesAfter1990Bis = games.stream()
        .filter(VideoGame::isAfter1990)
        .sorted((g1, g2) -> Integer.valueOf(g1.getReleaseYear()).compareTo(g2.getReleaseYear()))
        .toList();

    System.out.println("\nQ1 - Sort by release year games after 1990");
    gamesAfter1990.stream().forEach((g) -> System.out.println(g));
    System.out.println("Q1 - Bis method" + Joiner.on(",").join(gamesAfter1990Bis));

    var segaConsoleNames = consoles.stream()
        .filter((c) -> c.getCompanyName().equals("SEGA"))
        .map((c) -> c.getName())
        .toList();
    System.out.println("\nQ2 - ");
    segaConsoleNames.stream().forEach((g) -> System.out.println(g));

    var sixteenBitsConsoleNames = consoles.stream()
        .filter((c) -> c.getName().contains("16 bits"))
        .map((c) -> c.getName())
        .toList();

    System.out.println("\nQ3 - 16 bits consoles: ");
    sixteenBitsConsoleNames.stream().forEach((g) -> System.out.println("- " + g));

    System.out.println("\nQ4 - Nom du premier jeu sorti : ");
    Optional<VideoGame> minYearVideoGame = games.stream().min(Comparator.comparingInt((game) -> game.getReleaseYear()));
    if (!minYearVideoGame.isPresent()) {
      return;
    }
    System.out.println(minYearVideoGame.get().getName());

    var minYearVideosGames = games.stream()
        .filter((g) -> g.getReleaseYear() == minYearVideoGame.get().getReleaseYear()).toList();
    System.out.println("\nQ4 ++ - Au cas où il y a plusieurs jeux sortis la même année : ");
    System.out.println(Joiner.on(",").join(minYearVideosGames));

    System.out.println("\nQ5 - Nombre de jeux de chaque éditeur : ");
    var publishers = games.stream().map(g -> g.getPublisher()).distinct().toList();

    var groupedGamesByPublishers = games.stream()
        .collect(Collectors.groupingBy((g) -> g.getPublisher()))
        .entrySet().stream()
        .map((entry) -> new AbstractMap.SimpleEntry<String, Integer>(entry.getKey(), entry.getValue().size())).toList();
    System.out.println(Joiner.on(",").join(groupedGamesByPublishers));

  }
}

Exercice 3

Pour cet exercice, créer le projet avec gradle init et utiliser les annotations liées à la null safety.

  • Créer une classe Java IntCalculator qui permet de faire des opérations arithmétiques sur des entiers à partir d'une chaîne de caractères au format opérande1 opération opérande2 et retourne le résultat de cette opération.
    • les opérandes sont des entiers
    • Opétation est soit +, -, / ou *
    • Vous pouvez utiliser split pour séparer les différentes parties
    • Utilise les streams au maximum (utiliser les boucles au minimum)
  • Votre calculatrice mémorise toutes les opérations et leurs résultats.
  • Ecrire un programme Java qui permet de soit saisir un opération soit afficher l'historique des opérations selon les commandes de l'utilisateur.
    • Si l'utilisateur saisit une opération du type opérande1 opération opérande2, afficher le résultat et l'ajouter à l'historique.
    • Si l'utilisateur saisit h, afficher l'historique des opérations.
    • Si l'utilisateur saisit +, -, , afficher l'historique des opérations pour cette opérande.
    • Si l'utilisateur saisit exit, le programme s'arrête.
    • Si l'utilisateur saisit un entier, sa valeur est affichée et il est rajouté dans l'historique
  • Gérer les exceptions, notamment celle liées aux erreurs de saisie

  • Astuces: utiliser STR."" pour formater vos Chaînes de caractères.

exemple d'exécution
#  '>' signifie que c'est une entrée de l'utilisateur. Ce n'est pas un symble à inclure dans votre saisie
> 2 + 5
7
> 100 - 2000
-1900
> 42
42
> h
2 + 5 = 7
100 - 2000 = -1900
42
> +
2 + 5 = 7
> toto
saisie incorrecte
> 88 - 33 * 2
saisie incorrecte
> exit
bye bye

Exercice 4

Kotlin Heroes 2024, Problem A: 1-3-5.

In Berland, coins of worth 1, 3 and 5 burles are commonly used (burles are local currency).

Eva has to pay exactly 𝑛 burles in a shop. She has an infinite amount of coins of all three types. However, she doesn't like to pay using coins worth 1 burle — she thinks they are the most convenient to use.

Help Eva to calculate the minimum number of coins worth 1 burle she has to use, if she has to pay exactly 𝑛 burles. Note that she can spend any number of coins worth 3 and/or 5 burles.

  • Input
    • The first line contains one integer 𝑡 (1≤𝑡≤100 ) — the number of test cases.
    • Each test case consists of one line, containing one integer 𝑛(1≤𝑛≤100).
  • Output
    • For each test case, print one integer — the minimum number of 1-burle coins Eva has to use.
input
5
7
8
42
2
11
output
1
0
0
2
0

Exercice 5

Pour cet exercice, créer le projet avec gradle init et utiliser les annotations liées à la null safety.

  • Créer une classe Java ImprovedIntCalculator qui permet de faire des opérations arithmétiques sur des entiers à partir d'une chaîne de caractères au format opérande1 opération opérande2 opération2 opérande3 ... et retourne le résultat de cette opération.
    • les opérandes sont des entiers
    • Les opérandes écrites avec l'identifiant mi ou i est un entier permet de remplacer mi par le résultat dans l'historique d'indice i.
    • Opération est soit +, -, / ou *
    • Utilise les streams au maximum (utiliser les boucles au minimum)
    • / et * sont plus prioritaires que + et -
  • Votre calculatrice mémorise toutes les opérations et leurs résultats.
  • Ecrire un programme Java qui permet de soit saisir un opération soit afficher l'historique des opérations selon les commandes de l'utilisateur.
    • Si l'utilisateur saisit une opération du type opérande1 opération opérande2, afficher le résultat et l'ajouter à l'historique.
    • Si l'utilisateur saisit h, afficher l'historique des opérations.
    • Si l'utilisateur saisit +, -, , afficher l'historique des opérations pour cette opérande.
  • Gérer les exceptions, notamment celle liées aux erreurs de saisie
exemple d'exécution
#  '>' signifie que c'est une entrée de l'utilisateur. Ce n'est pas un symble à inclure dans votre saisie
> 2 + 5
7
> 100 - 2000 + 5
-1895
> h
2 + 5 = 7
100 - 2000 + 5 = -1895
> +
2 + 5 = 7
100 - 2000 + 5 = -1895
> toto
saisie incorrecte
> 88 - 33 * 2
22
> 88 - 33 * 2 / 3 + 5
67
> 7 + m0
14
> m2
22
> exit
bye bye