Partage
  • Partager sur Facebook
  • Partager sur Twitter

La bataille - Java - France IOI

Sujet résolu
    4 novembre 2019 à 16:07:37

    Bonjour,

    Je me permets de poster ici car je bloque sur cet exercice depuis plusieurs jours et malgré mes recherches (même dans d'autres langages) et mes tentatives, je n'arrive pas à avoir 100% de tests réussis.

    >>>

    Vous avez sûrement déjà joué, étant enfant, au jeu de cartes appelé la « bataille ». Les enfants algoréens aiment aussi beaucoup jouer à une variante bien plus simple de ce jeu, et vous devez faire l’arbitre des parties. Comme il y a beaucoup d’enfants souhaitant jouer en même temps et que vous ne pouvez pas tout surveiller, vous décidez d’écrire un programme informatique pour déterminer le vainqueur de chaque partie.

    Une partie se déroule ainsi :

    • On part d’un jeu contenant 52 cartes, chaque carte étant une lettre entre A et M, et chaque lettre étant présente 4 fois (avec différentes couleurs, mais on ne s’en occupera pas ici).
    • Les cartes, face cachée, sont mélangées et séparées en deux paquets (pas forcément de même taille !).
    • Les deux joueurs retournent la première carte de leur paquet : si les deux cartes sont identiques ils continuent à jouer, sinon celui qui a la carte la plus forte, c’est-à-dire la plus petite selon l’ordre alphabétique, gagne la partie.
    • Si un joueur n’a plus de carte, il perd ! Et oui, ce n’est pas très juste !
    • Si les deux joueurs n’ont en même temps plus de cartes, alors il y a égalité complète.

    Étant donnés les deux paquets de cartes, à vous de déterminer le gagnant.

    Entrée

    L'entrée contient deux lignes, correspondant respectivement aux cartes du joueur 1 et du joueur 2, dans l'ordre. Un jeu de cartes est constitué uniquement de lettre majuscules entre A et M (sans espaces).

    Sortie

    Sur la première ligne, il faut indiquer « 1 », « 2 » ou « = » selon que le gagnant est le premier ou le second joueur, ou bien qu’il y a égalité complète.

    Sur la seconde ligne, il faut indiquer le nombre d’égalités qui ont eu lieu avant que le jeu ne se termine.

    Exemples

    Exemple 1

    entrée :

    AABBDCCDEEFFGGHHIIJJKKLLMM
    AABBCCDDEEFFGGHHIIJJKKLLMM

    sortie :

    2
    4

    Exemple 2

    entrée :

    AA
    AABBCCDDEEFFGGHHIIJJKKLLMMBBDCCDEEFFGGHHIIJJKKLLMM

    sortie :

    2
    2

    Commentaires

    L'exemple 1 se déroule comme suit :

    1. A contre A, égalité ;
    2. A contre A, égalité ;
    3. B contre B, égalité ;
    4. B contre B, égalité ;
    5. D contre C : le C l'emporte.

    C'est donc le joueur 2 qui remporte la partie, après 4 égalités.

    Dans l'exemple 2, après deux égalités, le joueur 1 n'a plus de carte et donc perd la partie.

    >>>

    Voici pour le sujet de l'exercice. Concernant mon code, j'arrive à un résultat de 79% de tests réussis, mais 3 tests échouent car apparemment je cherche à comparer des cartes qui n'existent pas (outOfBoundaries). Je pense que le soucis vient du fait que dans cette dernière version de code, la différence de jeu entre joueurs n'est pas pris en compte pour les résultats.

    import algorea.Scanner;
    class Main {
       static Scanner input = new Scanner(System.in);
       
       public static void main(String[] args) {
       
          String joueur1 = input.nextLine();
          String joueur2 = input.nextLine();
          String gagnant = "unknown";
          int égalité = 0;
          
          int longueurMin = joueur1.length() - joueur2.length();
          if (longueurMin < 0) {
             longueurMin = -longueurMin;
          } else if (longueurMin == 0) {
             longueurMin = 26;
          }
          
          int numChar = 0;
          
          while((joueur1.charAt(numChar) == joueur2.charAt(numChar)) && (numChar < longueurMin)) {
             égalité++;
             numChar++;
          }
          
          if (joueur1.charAt(numChar) < joueur2.charAt(numChar)){
             gagnant = "1";
          } else if (joueur1.charAt(numChar) > joueur2.charAt(numChar)){
             gagnant = "2";
          } else if (joueur1.charAt(longueurMin-1) == joueur2.charAt(longueurMin-1)){
             gagnant = "=";
          }
          
          System.out.println(gagnant);
          System.out.println(égalité);
       }
    }

    Les 3 tests qui échouent me renvoie ça comme message :

    Test 9 Erreur

    Erreur d'exécution. Voici ce qui a été affiché :

    Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 13
    	at java.lang.String.charAt(String.java:658)
    	at Main.main(main.java:21)
    
    0 %
    Test 10 Erreur

    Erreur d'exécution.

    0 %
    Test 11 Erreur

    Erreur d'exécution.

    0 %

    Le soucis pour moi, actuellement, c'est que même en essayant avec une syntaxe différement, je n'arrive apparemment pas à couvrir tous les cas de figures. Celui qui me donne le plus de tests réussis est donc le code ci-dessus, où je compte d'abord les égalités et ensuite, je compare les cartes restantes. Mais ça ne suffit pas apparemment.

    Il ne me manque que cet exercice pour valider le niveau 2 et passer au niveau 3. Je précise que je suis en reconversion professionnelle, actuellement en stage, donc il n'y a pas de devoir ou de notations derrière, c'est vraiment dans le cadre de mon stage que je dois faire ces exercices pour m'auto-former au Java (en tout cas aux bases) pour ensuite intégrer une équipe avec des Dev plus expérimentés pour faire des choses plus poussées que de l'algorithme.

    Donc, si vous avez des conseils, des indices ou des corrections à me donner, je suis preneuse :) j'ai fait tous les exercices suivants sans trop de problème, mais celui-là le résiste.

    Merci d'avance,

    Cordialement.

    -
    Edité par HappyBadger 6 novembre 2019 à 9:53:00

    • Partager sur Facebook
    • Partager sur Twitter

    "Ce sont nos choix qui montrent qui nous sommes, bien plus que nos aptitudes"

    Albus Dumbledore

    Potterhead forever, proud Hufflepuff

      4 novembre 2019 à 18:59:47

      Salut,

      Déjà évite les noms de variables avec des accents ("égalité" -> "egalite").

      Ensuite tu as peut-être un cas de test où les inputs sont vides tout simplement.

      • Partager sur Facebook
      • Partager sur Twitter
        5 novembre 2019 à 9:57:53

        Salut,

        Je ne mets pas d'accent pour les autres langages, mais comme Java les supporte, j'avoue que je fais une exception.

        J'ai testé, en fait les inputs ne sont jamais vide, il y a toujours une distribution de 52 cartes... Mais je vais vérifier ce paramètre... Après, j'ai un peu avancé, je vais remettre mon code le plus récent ainsi que les retours du programme :

        import algorea.Scanner;
        class Main {
           static Scanner input = new Scanner(System.in);
           
           public static void main(String[] args) {
           
              String joueur1 = input.nextLine();
              String joueur2 = input.nextLine();
              String gagnant = "unknown";
              
              // Je calcule la longueur minimale
              int longueurMin = 0;
              if (joueur1.length() < joueur2.length()) {
                 longueurMin = joueur1.length();
              } else if (joueur2.length() < joueur1.length()) {
                 longueurMin = joueur2.length();
              } else if (joueur1.length() == joueur2.length()){
                 longueurMin = 26;
              }
              
              // tant que les joueurs ont des cartes similaires, j'incrémente l'égalité et je passe à la carte suivante
              int égalité = 0;
              int numChar= 0;
              while((numChar < longueurMin-1) && (joueur1.charAt(numChar) == joueur2.charAt(numChar))) {
                 égalité++;
                 numChar++;
              }
              
              if (joueur1.charAt(numChar) < joueur2.charAt(numChar)){
                 gagnant = "1";
              } else if (joueur1.charAt(numChar) > joueur2.charAt(numChar)){
                 gagnant = "2";
              } else if (joueur1.charAt(numChar) == joueur2.charAt(numChar)){
                 gagnant = "=";
                 égalité++;
              }
              System.out.println(gagnant);
              System.out.println(égalité);
           }
        }

        Et voici le retour :

        Test 1 Succès

        Exécuté en 0 seconde.

        100 %
        Test 2 Succès

        Exécuté en 0 seconde.

        100 %
        Test 3 Succès

        Exécuté en 0 seconde.

        100 %
        Test 4 Succès

        Exécuté en 0 seconde.

        100 %
        Test 5 Succès

        Exécuté en 0 seconde.

        100 %
        Test 6 Succès

        Exécuté en 0 seconde.

        100 %
        Test 7 Succès

        Exécuté en 0 seconde.

        100 %
        Test 8 Succès

        Exécuté en 0 seconde.

        100 %
        Test 9 Échec

        La réponse donnée par votre programme est incorrecte. Il a affiché :

        =
        13
        

        au lieu de :

        1
        13
        
        0 %
        Test 10 Échec

        La réponse donnée par votre programme est incorrecte.

        0 %
        Test 11 Succès

        Exécuté en 0 seconde.

        100 %
        Test 12 Succès

        Exécuté en 0 seconde.

        100 %
        Test 13 Succès

        Exécuté en 0 seconde.

        100 %
        Test 14 Succès

        Exécuté en 0 seconde.

        100 %
         
        TOTAL Échec Vous avez réussi 12 tests sur 14. 86 %


        Donc ça avance, mais c'est pas encore ça -___-

        • Partager sur Facebook
        • Partager sur Twitter

        "Ce sont nos choix qui montrent qui nous sommes, bien plus que nos aptitudes"

        Albus Dumbledore

        Potterhead forever, proud Hufflepuff

          5 novembre 2019 à 20:07:11

          Hello,

          Pour simplifier la résolution, peux-tu donner les jeux de test 9 et 10 ?

          Petite remarque : tu peux simplifier ton code déterminant la valeur de longueurMin en plaçant juste :

          int longueurMin = Math.min(joueur1.length(),joueur2.length());

          Si les deux joueurs ont le même nombre de cartes, alors chaque paquet contient 26 cartes et longueurMin vaut 26

          -
          Edité par Dropper 5 novembre 2019 à 20:19:50

          • Partager sur Facebook
          • Partager sur Twitter
            6 novembre 2019 à 9:52:16

            Bonjour,

            Pour répondre à Dropper, je n'ai pas les jeux des test 9 et 10, généralement les exemples correspondent aux premiers tests, c'est d'ailleurs très frustrant de ne pas pouvoir comparer les jeux. En effet je n'ai pas utilisé Math car l'import de Math n'était pas précisé dans l'énoncé, mais j'y penserai pour la prochaine fois.

            La bonne nouvelle, c'est que grâce à un autre membre sur France-IOI, j'ai enfin pu résoudre l'exercice :D En fait, je n'arrivais pas à concevoir comment vérifier certaines conditions, mais une fois que j'ai eu la solution par cet autre membre, ça m'a semblé évident (évidemment). Je la mets donc ci-dessous, ça peut servir à débloquer quelqu'un d'autre :)

            import algorea.Scanner;
            class Main {
               static Scanner input = new Scanner(System.in);
               
               public static void main(String[] args) {
               
                  String joueur1 = input.nextLine();
                  String joueur2 = input.nextLine();
                  String gagnant = "unknown";
                  
                  // Je calcule la longueur minimale
                  int longueurMin = 0;
                  if (joueur1.length() < joueur2.length()) {
                     longueurMin = joueur1.length();
                  } else if (joueur2.length() < joueur1.length()) {
                     longueurMin = joueur2.length();
                  } else if (joueur1.length() == joueur2.length()){
                     longueurMin = 26;
                  }
                  
                  // tant que les joueurs ont des cartes similaires, j'incrémente l'égalité et je passe à la carte suivante
                  int égalité = 0;
                  int numChar= 0;
                  while((numChar < longueurMin-1) && (joueur1.charAt(numChar) == joueur2.charAt(numChar))) {
                     égalité++;
                     numChar++;
                  }
                  
                  // Si les cartes des joueurs sont similaires, j'incrémente égalité
                  if (joueur1.charAt(numChar) == joueur2.charAt(numChar)){
                       égalité++;
                  }
                  // Si la carte du joueur 1 est plus petite que la carte du joueur 2, le gagnant est 1
                  if (joueur1.charAt(numChar) < joueur2.charAt(numChar)){
                     gagnant="1";
                  // Sinon si la carte du joueur 1 et du joueur 2 sont similaires ET si le jeu du joueur 1 est plus long, le gagnant est 1
                  } else if (joueur1.charAt(numChar) == joueur2.charAt(numChar) && (joueur1.length() > joueur2.length())){
                     gagnant = "1"; 
                  // Sinon si la carte du joueur 1 est supérieur à la carte du joueur 2, le gagnant est 2
                  } else if (joueur1.charAt(numChar) > joueur2.charAt(numChar)){
                     gagnant = "2";
                  // Sinon si la carte du joueur 1 et du joueur 2 sont similaires ET si le jeu du joueur 1 est plus court, le gagnant est 2
                  } else if (joueur1.charAt(numChar) == joueur2.charAt(numChar) && (joueur1.length() < joueur2.length())){
                     gagnant = "2"; 
                  // Sinon si la dernière carte du joueur 1 et 2 sont similaires, pas de gagnant mais égalité
                  } else if (joueur1.charAt(longueurMin-1) == joueur2.charAt(longueurMin-1)){
                     gagnant = "=";
                  } 
                  System.out.println(gagnant);
                  System.out.println(égalité);
               }
            }

            Il m'aura pris 6 jours, et en plus la correction est bien plus simple que mon code (mais je ne la partagerai pas :D ), mais je suis quand même contente d'y être parvenue (avec de l'aide, bien entendu).

            Merci aux personnes qui se sont penchées sur la question !

            Bonne journée !



            • Partager sur Facebook
            • Partager sur Twitter

            "Ce sont nos choix qui montrent qui nous sommes, bien plus que nos aptitudes"

            Albus Dumbledore

            Potterhead forever, proud Hufflepuff

            La bataille - Java - France IOI

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown