Partage
  • Partager sur Facebook
  • Partager sur Twitter

problème d'arrondis avec la vérificatio france ioi

Sujet résolu
    8 juillet 2022 à 22:55:27

    Bonjour,

    je ne sais pas si je suis le seul à mettre confronté à ce problème mais je ne comprend pas comment je devrait faire.

    ENONCÉ:

    On a découvert de vieilles archives au sein de la bibliothèque, de nombreux manuscrits écrits dans diverses langues. On souhaite étudier plus en détail ces manuscrits mais comme tous les bibliothécaires ne parlent pas toutes ces langues, il faut d’abord déterminer la langue pour pouvoir choisir le bon bibliothécaire.

    Pour déterminer la langue de manière automatique, un des bibliothécaires vous propose de déterminer la lettre la plus fréquente dans chaque texte, mais vous savez que cette technique n’est pas assez précise pour donner de bon résultats.

    Vous décidez donc plutôt de regarder à quelles fréquences apparaissent chacune des lettres de l’alphabet.

    Limites de temps et de mémoire (Python)

    • Temps : 0,1 s sur une machine à 1 GHz.
    • Mémoire : 8 000 ko.

    Contraintes

    La ligne de texte contient moins de 10 000 caractères.

    Entrée

    Une seule ligne de texte, ne contenant pas de lettres accentuées, mais pouvant contenir des signes de ponctuation ou des chiffres.

    Sortie

    Pour chacune des lettres de l’alphabet, il faut afficher, sur une ligne, sa fréquence d’apparition dans le texte définie comme le nombre de fois où la lettre est présente, divisé par le nombre total de lettres du texte (et pas le nombre total de caractères).


    Exemple entrée : Le francais est une langue romane, de la famille des langues indo-europeennes. sortie : 0.109375 0.000000 0.015625 0.046875 0.203125 0.031250 0.031250 0.000000 0.046875 0.000000 0.000000 0.093750 0.031250 0.125000 0.046875 0.015625 0.000000 0.046875 0.078125 0.015625 0.062500 0.000000 0.000000 0.000000 0.000000 0.000000



    Je dois arrondir un nombre à la 6ème décimale:

    alphabet = {'a': 0, 'b': 0, 'c': 0, 'd': 0, 'e': 0, 'f': 0, 'g': 0, 'h': 0, 'i': 0, 'j': 0, 'k': 0, 'l': 0, 'm': 0, 'n': 0, 'o': 0, 'p': 0, 'q': 0, 'r': 0, 's': 0, 't': 0, 'u': 0, 'v': 0, 'w': 0, 'x': 0, 'y': 0, 'z': 0}
    line = input().lower()
    nb_letter = 0
    for char in line:
        if char in alphabet:
            alphabet[char] += 1
            nb_letter += 1
    for letter in alphabet:
        proportion = alphabet[letter] / nb_letter
        proportion = round(proportion, 6)
        print(proportion)

    A priori pas de problèmes dans mon code parce que quand je l'exécute dans le terminal j'obtiens la sortie souhaitée.

    Mais voici ce que me dit la vérification de france ioi:

    Message de l'évaluateur :
    
    Nombre total de valeurs affichées : 26
    Votre valeur numero 1 (0.0468750000) est à une distance supérieure à 0.01 de la reponse attendue.
    
    Erreur dans le résultat.

    il ne supprime pas les 0 inutiles à la fin du nombre.

    Merci d'avance pour ceux qui m'aideront :)


    -
    Edité par Quegzacov 9 juillet 2022 à 14:19:20

    • Partager sur Facebook
    • Partager sur Twitter

    "A computer is like air conditioning, it becomes useless when you open Windows" Linus Torvalds

      9 juillet 2022 à 1:52:26

      Ha! Ce cher France IOI ... As-tu l'énoncé exact de ce qu'on te demande?
      Si c'est seulement d'afficher exactement 6 décimales, pas de problème:
          proportion = (str(round(proportion, 6)) + '0'*6)[:8]

      Ou encore:

          print("%.6f" % (round(proportion, 6)))

      Si ta ligne peut contenir autre chose que des lettres et que tu dois calculer la proportion par rapport à tous les caractères, tu devras augmenter le nombre de caractères en dehors du if.

      Voici une façon plus simple de générer ton dictionnaire alphabet:

      from string import ascii_lowercase

      alphabet = {a: 0 for a in ascii_lowercase}

      -
      Edité par PierrotLeFou 9 juillet 2022 à 5:33:42

      • Partager sur Facebook
      • Partager sur Twitter

      Le Tout est souvent plus grand que la somme de ses parties.

        9 juillet 2022 à 14:20:35

        PierrotLeFou a écrit:

        Ha! Ce cher France IOI ... As-tu l'énoncé exact de ce qu'on te demande?
        Si c'est seulement d'afficher exactement 6 décimales, pas de problème:
            proportion = (str(round(proportion, 6)) + '0'*6)[:8]

        Ou encore:

            print("%.6f" % (round(proportion, 6)))

        Si ta ligne peut contenir autre chose que des lettres et que tu dois calculer la proportion par rapport à tous les caractères, tu devras augmenter le nombre de caractères en dehors du if.

        Voici une façon plus simple de générer ton dictionnaire alphabet:

        from string import ascii_lowercase

        alphabet = {a: 0 for a in ascii_lowercase}

        -
        Edité par PierrotLeFou il y a environ 8 heures


        J'ai rajouté l'énoncé dans mon précédent post

        • Partager sur Facebook
        • Partager sur Twitter

        "A computer is like air conditioning, it becomes useless when you open Windows" Linus Torvalds

          9 juillet 2022 à 18:53:56

          Il n'est pas dit dans l'énoncé que  tu dois arrondir (round) les valeurs.
          Le reste tu le fais correctement.
          Utilises mon print pour afficher avec 6 décimales.
          Il fera un round de toute façon.
          Ce n'est pas la première fois que France IOI n'est pas précis dans ses énoncés.
          Si ça ne marche pas, utilises ma première méthode avec le str() mais sans le round()
          -
          >>> a=3.13456765456565                                                                                                  
          >>> a                                                                                                                   
          3.13456765456565                                                                                                        
          >>> print("%.6f" % (a))                                                                                                 
          3.134568

          -

          Le problème avec les round est que si tu fais la somme des proportions, le total risque de dépasser 1.0, ce que France IOI ne veut peut-être pas.

          La seule chose qui prend beaucoup de mémoire est la ligne et on te garantit que c'est moins de 10 000 caractères.

          Ce qui prend le plus de temps est l'accumulation des fréquences et ça prend beaucoup moins que la limite.

          -
          Edité par PierrotLeFou 10 juillet 2022 à 3:25:39

          • Partager sur Facebook
          • Partager sur Twitter

          Le Tout est souvent plus grand que la somme de ses parties.

            10 juillet 2022 à 9:04:03

            J'ai beau essayer les 2 techniques rien ne marche. L'interpréteur python de France-ioi fonctionne mal. J'obtiens toujours beaucoup trop de zéros sous prétexte que c'est un float...
            • Partager sur Facebook
            • Partager sur Twitter

            "A computer is like air conditioning, it becomes useless when you open Windows" Linus Torvalds

              10 juillet 2022 à 10:40:33

              Quegzacov a écrit:

              J'ai beau essayer les 2 techniques rien ne marche. L'interpréteur python de France-ioi fonctionne mal. J'obtiens toujours beaucoup trop de zéros sous prétexte que c'est un float...


              Montre ton code modifié avec les propositions présentées ci-dessus
              • Partager sur Facebook
              • Partager sur Twitter

              Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
              La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

              Anonyme
                10 juillet 2022 à 13:14:35

                -

                -
                Edité par Anonyme 11 juillet 2022 à 0:56:46

                • Partager sur Facebook
                • Partager sur Twitter
                  10 juillet 2022 à 17:54:14

                  @ErispoeLeNarvalo:
                  Pas certain d'avoir compris ce que j'ai loupé ...
                  Voici ma version abrégée:
                  -
                  from string import ascii_lowercase
                  from collections import Counter
                  alphabet = {a: 0 for a in ascii_lowercase}
                  addition = dict(Counter(c for c in input().lower() if c in alphabet))
                  alphabet.update(addition)
                  nb = sum(addition.values())
                  for fr in alphabet.values():
                      print("%.6f" % (fr/nb))

                  -
                  Edité par PierrotLeFou 10 juillet 2022 à 18:44:36

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Le Tout est souvent plus grand que la somme de ses parties.

                  Anonyme
                    10 juillet 2022 à 20:17:39

                    J'ai dis de la m$rde j'ai cru qu'il n'avait pas utilisé lower()
                    Tu as quel résultat ?
                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 juillet 2022 à 0:47:10

                      Mon code donne ceci:

                      Avec la phrase: Le francais est une langue romane, de la famille des langues indo-europeennes.
                      -
                      0.109375
                      0.000000
                      0.015625
                      0.046875
                      0.203125
                      0.031250
                      0.031250
                      0.000000
                      0.046875
                      0.000000
                      0.000000
                      0.093750
                      0.031250
                      0.125000
                      0.046875
                      0.015625
                      0.000000
                      0.046875
                      0.078125
                      0.015625
                      0.062500
                      0.000000
                      0.000000
                      0.000000
                      0.000000
                      0.000000

                      -

                      Si j'ajoute la ligne suivante à la fin:

                      print(sum(round(fr/nb, 6) for fr in alphabet.values()))

                      J'obtiens:

                      1.0

                      -
                      Edité par PierrotLeFou 11 juillet 2022 à 1:02:51

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Le Tout est souvent plus grand que la somme de ses parties.

                        11 juillet 2022 à 11:46:21

                        le problème ne doit pas être l'arrondi, car selon le message, la fréquence qu'il attend est soit supérieure à 0.056875 soit inférieure à 0.036875 (soit 0.0465875 +/-0.01) ; donc un problème de comptage de lettre ou de calcul

                        -
                        Edité par umfred 11 juillet 2022 à 11:46:51

                        • Partager sur Facebook
                        • Partager sur Twitter
                          11 juillet 2022 à 15:12:36

                          Il faudrait que Quegzacov nous donne son dernier code et le résultat qu'il obtient avec l'exemple.
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Le Tout est souvent plus grand que la somme de ses parties.

                            11 juillet 2022 à 22:40:58

                            C'est pas demandé d'arrondir.

                            print(str(le_calcul)[:8]) ça le fait pas ?

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Python c'est bon, mangez-en. 

                              12 juillet 2022 à 0:56:22

                              Et si on a moins de 6 chiffres aprèes la virgule?
                              Mon premier post en parle.
                              • Partager sur Facebook
                              • Partager sur Twitter

                              Le Tout est souvent plus grand que la somme de ses parties.

                                12 juillet 2022 à 9:19:08

                                Ce n'est pas nécessaire d'arrondir ou même d'avoir un nombre de décimales fixe, la vérification de France-IOI est faite sur les valeurs et non l'affichage. L'exercice en question pour ceux qui veulent tester.

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  12 juillet 2022 à 9:53:35

                                  ЯК a écrit:

                                  Ce n'est pas nécessaire d'arrondir ou même d'avoir un nombre de décimales fixe, la vérification de France-IOI est faite sur les valeurs et non l'affichage. L'exercice en question pour ceux qui veulent tester.


                                  Bonjour.

                                  J'ai voulu me prêter à l'exercice mais y'a déjà un truc qui me chagrine dans les réponses de l'exemple donné.

                                  Comment arrive-t-il (le site internet) à trouver des fréquences nulles sauf à compter des choses à ne pas prendre en compte ?

                                  Pour ma part, après formatage à 6 chiffres, j'ai :

                                  0.015625
                                  0.015625
                                  0.015625
                                  0.031250
                                  0.031250
                                  0.031250
                                  0.046875
                                  0.046875
                                  0.046875
                                  0.046875
                                  0.062500
                                  0.078125
                                  0.093750
                                  0.109375
                                  0.125000
                                  0.203125

                                  Mon code est le suivant :

                                  from string import ascii_lowercase
                                  from collections import Counter
                                  
                                  phrase = "Le francais est une langue romane, de la famille des langues indo-europeennes."
                                  nbLettres = sum([1 for _ in phrase.lower() if _ in ascii_lowercase])
                                  frequence = [v / nbLettres for v in Counter([c for c in phrase.lower() if c in ascii_lowercase]).values()]
                                  
                                  frequence.sort()
                                  
                                  for _ in frequence:
                                      print("%.6f" % _)

                                  -
                                  Edité par PB68 12 juillet 2022 à 10:33:16

                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  PB68

                                    12 juillet 2022 à 10:35:09

                                    PB68 a écrit:

                                    Comment arrive-t-il (le site internet) à trouver des fréquences nulles ?

                                    Ce sont les lettres absentes dans la chaîne.

                                    Il ne faut pas chercher trop loin, l'exercice consiste à compter les occurrences de toutes les lettres de A à Z, hors accents, ponctuations etc, pour ensuite afficher leur ratio dans la phrase, toujours en ignorant les caractères qui ne sont pas des lettres.

                                    La solution de l'OP était correcte dans l'idée, sauf que France-IOI utilise une version obsolète de Python 3 où les dictionnaires ne sont pas ordonnés et qu'il n'est pas non-plus nécessaire d'arrondir les calcules.
                                    Je pense que la solution attendu devrait ressembler à cela :

                                    ls, n = [0] * 26, 0
                                    for c in input().lower():
                                        if c.isalpha():
                                            ls[ord(c) - 97] += 1 # ord('A') -> 97
                                            n += 1
                                    
                                    for x in ls:
                                        print(x / n)
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      12 juillet 2022 à 11:28:34

                                      ЯК a écrit:

                                      PB68 a écrit:

                                      Comment arrive-t-il (le site internet) à trouver des fréquences nulles ?

                                      Ce sont les lettres absentes dans la chaîne.

                                      ...

                                      Ah oui, effectivement, y'a 26 lignes donc c'était évident au final !!!
                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      PB68

                                        12 juillet 2022 à 11:52:52

                                        comme le dictionnaire est créé en rentrant les lettres dans l'ordre, il ne devrait pas y avoir de problème à la restitution ? sinon, en forçant l'ordre au niveau du for => for letter in sorted(alphabet)
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          12 juillet 2022 à 13:57:37

                                          umfred a écrit:

                                          comme le dictionnaire est créé en rentrant les lettres dans l'ordre, il ne devrait pas y avoir de problème à la restitution ?

                                          France-IOI utilise encore Python 3.4. Donc les dictionnaire ne sont pas ordonnés.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            12 juillet 2022 à 15:02:03

                                            Pour garantir l'ordre, il suffit de faire la boucle sur ascii_lowercase et d'afficher l'entrée correspondante dans le dictionnaire.
                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            Le Tout est souvent plus grand que la somme de ses parties.

                                              16 juillet 2022 à 17:59:51

                                              ЯК a écrit:

                                              France-IOI utilise encore Python 3.4. Donc les dictionnaire ne sont pas ordonnés.


                                              C'était en effet un problème d'ordre. J'ai vérifié et France-IOI utilise CPython3.2.

                                              Voici ma solution un peu barbare :lol::

                                              alphabet = {'a': 0, 'b': 0, 'c': 0, 'd': 0, 'e': 0, 'f': 0, 'g': 0, 'h': 0, 'i': 0, 'j': 0, 'k': 0, 'l': 0, 'm': 0, 'n': 0, 'o': 0, 'p': 0, 'q': 0, 'r': 0, 's': 0, 't': 0, 'u': 0, 'v': 0, 'w': 0, 'x': 0, 'y': 0, 'z': 0}
                                              counter = [0 for i in range(26)]
                                              line = input().lower()
                                              nb_letter = 0
                                              for char in line:
                                                  if char in alphabet:
                                                      counter[ord(char) - ord('a')] += 1
                                                      nb_letter += 1
                                              for val in counter:
                                                  proportion = val / nb_letter
                                                  print(proportion)



                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              "A computer is like air conditioning, it becomes useless when you open Windows" Linus Torvalds

                                                16 juillet 2022 à 18:20:12

                                                Au lieu de tester si le caractère est dans alphabet, tu aurais pu faire 'a' <= char <= 'z'
                                                • Partager sur Facebook
                                                • Partager sur Twitter

                                                Le Tout est souvent plus grand que la somme de ses parties.

                                                problème d'arrondis avec la vérificatio 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