Aller au contenu

E05 - Mot le plus long⚓︎

Le problème

Mot le plus long

Proposition 1⚓︎

🐍 Script Python
def mot_le_plus_long(chaine_caractère: str) -> int:
    """Cette fonction prend en paramètre une chaine de caractère et renvoie le nombre de caractère du plus long mot de cette chaine.
    >>> 74
        ecrivez une fonction qui trouve la longueur du plus long mot dans ce texte
    8
    """
    chaine_caractère = chaine_caractère.split()
    mot = ""
    for x in chaine_caractère:
        if len(mot) < len(x):
            mot = x
    return len(mot)

# tests
import doctest
doctest.testmod()

# Entrée
nb_caractère = int(input())
chaine_caractère = input()

# Sortie
print(mot_le_plus_long(chaine_caractère))
  • Algorithme bizarre : confusion entre les mots et les lettres.
  • mot n'est pas le meilleur choix, c'est la longueur qu'il vaut mieux conserver et mettre à jour.
  • Revoir le doctest.
  • Ne pas faire de ligne de code trop longue. Maximum 80 caractères.

Proposition 2⚓︎

🐍 Script Python
def recherche_mot_long(liste_mots : list) -> int:
    """ Renvoie la longueur du mot le plus long de la liste
    >>> recherche_mot_long(['bonjour','salutation','coucou'])
    10
    >>> recherche_mot_long(['ahahah','ok','voiture'])
    7
    """

    longeur_plus_longue = len(liste_mots[0])

    for x in range(1,len(liste_mots)):
        if len(liste_mots[x]) > longeur_plus_longue:
            longeur_plus_longue = len(liste_mots[x])
    return longeur_plus_longue

# tests
import doctest
doctest.testmod()

# Entrée
nb_caractère = int(input())
liste_mots = list(input().split())

# Sortie
print(recherche_mot_long(liste_mots))
  • split, c'est tricher ici aussi.
  • On préfère faire le découpage dans la fonction, pas avant.

Proposition 3⚓︎

🐍 Script Python
nombre_caractères = int(input())

liste_mots = input().split(" ")

# On crée une liste où, à la place d'avoir les mots, on a leur longueur en utilisant `map`
liste_longueur_mots = list(map(len, liste_mots))

# Et on affiche la plus grande longueur de la liste des longueurs de mots
print(max(liste_longueur_mots))
  • On attendait une fonction, surtout pour présenter ici un style fonctionnel.
  • Quitte à avoir un style fonctionnel, ne pas créer de liste intermédiaire, mais travailler plutôt avec un itérateur.
  • Présenter cette variante avec split en commentaire après avoir résolu le problème sans.

Proposition 4⚓︎

🐍 Script Python
def mot_le_plus_long(phrase : str) -> int:
    """Renvoie la longueur du plus long mot.
    >>> mot_le_plus_long('ecrivez une fonction qui trouve la longueur du plus long mot dans ce texte')
    8
    """
    liste = phrase.split()
    plus_grand_mot = ""
    for i in liste:
        if (len(plus_grand_mot) < len(i)):
            plus_grand_mot = i
    print(len(plus_grand_mot))

# Test
import doctest
doctest.testmod()

# Entrées
nb_lettres = int(input())
phrase = input()
if not (0 <= nb_lettres <= 200):
    raise ValueError("Trop de lettres")

# Sortie
mot_le_plus_long(phrase)
  • i et plus_grand_mot : mauvais noms.
  • Le raise est inutile ici ; les fichiers d'entrée sont censés être bons.

Proposition 5⚓︎

🐍 Script Python
def cherche_mot_long(nb_caractère: int, phrase):
    """ trouve le mot le plus long dans la phrase 
    et renvoie le nombre du plus grand caractère 
    >>> cherche_mot_long(74, ['ecrivez', 'une', 'fonction', 'qui', 'trouve', 'la', 'longueur', 'du', 'plus', 'long', 'mot', 'dans', 'ce', 'texte'])
    8
    """
    if nb_caractère > 200:
        raise ValueError("nombre de caractère trop grand")
    else:
        longeur_mot = len(phrase[0])
        for x in phrase:
            if len(x) >= longeur_mot:
                longeur_mot = len(x)
        return longeur_mot

import doctest
doctest.testmod()

nb_caractère = int(input())
phrase = input().split()
print(cherche_mot_long(nb_caractère, phrase))
  • Quitte à utiliser un split, il vaut mieux le faire dans la fonction.
  • x : mauvais nom, mot c'est mieux.
  • raise inutile.

Proposition 6⚓︎

🐍 Script Python
def mot_le_plus_long(texte):
    """ Cette fonction prend en paramètre une chaine de caractères, et elle renvoie le nombre de caractères du plus long mot de cette chaine.

    Je n'ai pas activer le test, car celui-ci faisait bugger le programme et je ne sais pas comment le rendre juste.
    # >>> mot_le_plus_long(ecrivez une fonction qui trouve la longueur du plus long mot dans ce texte)
    8
    """

    ans = ""
    for lettre in texte:
        if len(lettre)>len(ans):
            ans = lettre
    return ans

# tests
import doctest
doctest.testmod()

# Entrée
nb_caractères = int(input())
texte = input().split()

# Sortie
print(len(mot_le_plus_long(texte)))
  • Il manque des guillemets au texte dans le doctest.
  • Il faut mettre le split (si on l'utilise) dans la fonction.
  • lettre : mauvais nom d'identifiant. mot serait mieux.
  • ans : c'est pas top, c'est une abréviation d'un mot anglais (answer).

Soit on code en anglais, soit en français. Le mélange n'est pas fabuleux...

Proposition 7⚓︎

🐍 Script Python
# 0- Coeur du programme

def mot_le_plus_long(nb_lettres: int, chaine_mots: list) -> int:
    """ Renvoie le nombre de caractère du plus long mot de chaine_mots
    >>> mot_le_plus_long(11, ["Hello", "World"])
    5
    >>> mot_le_plus_long(74, ["ecrivez", "une", "fonction", "qui", "trouve", "la", "longueur", "du", "plus", "long", "mot", "dans", "ce", "texte"])
    8
    """

    plus_long = 0
    for mot in chaine_mots:
        longueur_mot = len(mot)
        if longueur_mot > plus_long:
            plus_long = longueur_mot
    return plus_long

# 1- Tests

import doctest
doctest.testmod()

# 2- Lecture des entrées

nb_lettres = int(input())
chaine_mots = input().split()

# 3- Appel de la fonction / Sortie

print(mot_le_plus_long(nb_lettres, chaine_mots))
  • Il faut mettre le split (si on l'utilise) dans la fonction.
  • Aérer le doctest.
  • Au lieu de passer une liste en paramètre, il vaut mieux la chaine.
    • C'est plus cohérent avec la longueur donnée aussi en paramètre.
  • plus_long : on peut faire mieux avec plus_grande_longueur.

Proposition 8⚓︎

🐍 Script Python
def longueur_max_mot(texte : str) -> int :
    """ Renvoie l'entier correspondant à la longueur du plus long mot 
    de la chaine de caractère 'texte'. 

    >>> texte = 'ecrivez une fonction qui trouve la longueur du plus long mot dans ce texte'
    >>> longueur_max_mot(texte)
    8

    """ 
    max = 0
    for mot in texte :
        if len(mot) > max :
            max = len(mot)
    return max

# tests
import doctest
doctest.testmod()

# Entrée
nb_caractères = int(input())
assert 1 <= nb_caractères <= 200
texte = input().split()

# Sortie
print(longueur_max_mot(texte))
  • Bon doctest, mais il échoue, en cause : le split placé avant l'appel à la fonction.
  • assert inutile.
  • L'annotation de type est fausse ; pour le corriger, il faut placer le split dans la fonction...
  • max et texte ne sont pas des noms idéaux.

Corrigé du professeur⚓︎

🐍 Script Python
"""
author: Franck CHAMBON
problem: https://prologin.org/train/2003/semifinal/mot_le_plus_long
"""

def longueur_plus_long_mot(chaine: str) -> int:
    """Renvoie la longueur du mot le plus long.

    >>> longueur_plus_long_mot("ecrivez une fonction qui trouve\
                    la longueur du plus long mot dans ce texte")
    8

    >>> longueur_plus_long_mot("aaa b")
    3

    >>> longueur_plus_long_mot("a bbb")
    3

    >>> longueur_plus_long_mot("cc")
    2

    """
    taille = len(chaine)
    longueur_max = 0
    longueur = 0
    for i in range(taille):
        if chaine[i] == ' ':
            if longueur_max < longueur:
                longueur_max = longueur
            longueur = 0
        else:
            longueur += 1
    # test du dernier mot
    if longueur_max < longueur:
        longueur_max = longueur

    return longueur_max


import doctest
doctest.testmod()

taille = int(input())
chaine = input()

print(longueur_plus_long_mot(chaine))
  • On conseille d'ajouter des tests utiles simples en plus de ceux proposés par le problème. Des cas délicats (corner cases en anglais).
  • On peut proposer en bonus une version fonctionnelle courte :
🐍 Script Python
def longueur_plus_long_mot(chaine: str) -> int:
    return max(map(len, chaine.split()))

map renvoie un itérateur et aucune liste intermédiaire n'est créée.