IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Besoin D'aide sur un Exercice de programmation mon code est trop lent [Python 3.X]


Sujet :

Python

  1. #1
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    juin 2023
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 16
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : juin 2023
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Besoin D'aide sur un Exercice de programmation mon code est trop lent
    salut je suis maintenant bloqué sur exercice depuis 2 3 jours j'arrive a résoudre le problème mais je ne valide pas tous les test car mon programme est trop lent je n'arrive a trouver une solution pour le rendre plus rapide je viens donc demander conseil

    Voici l'énoncé du problème :

    Énoncé
    Dans une liste de nombres entiers, une répétition est une paire de nombres égaux qui sont côte à côte. Par exemple, dans la liste 1 3 3 4 2 2 1 1 1, il y a quatre répétitions : les deux 3, puis les deux 2, puis les deux 1 qui suivent, et enfin les deux 1 de la fin de la liste.

    On vous donne une liste de nombres entiers. Écrivez un programme qui calcule le nombre minimum de répétitions qu'il peut rester dans la liste une fois que l'on a retiré toutes les occurrences d'un des nombres.

    Entrée
    La première ligne de l'entrée contient un entier nbNombres, avec 2 ≤ nbNombres ≤ 50 000.

    Les nbNombres lignes suivantes contiennent chacune un entier compris entre 0 et nbNombres.

    Sortie
    Vous devez afficher un nombre : le nombre minimum de répétitions qu'il est possible d'obtenir après avoir supprimé toutes les occurrences d'un des nombres de la liste.

    Exemples
    Voici un exemple d'entrée :

    9
    1
    3
    2
    2
    3
    4
    4
    2
    1
    La liste de 9 nombres est "1 3 2 2 3 4 4 2 1". Elle contient deux répétitions (les deux premiers 2 et les deux 4) :

    retirer les 1 laisse les deux répétitions ;
    retirer les 2 rapproche les trois, donc on a supprimé une répétition et en rajoute une. Il reste donc deux répétitions ;
    retirer les 3 laisse les deux répétitions ;
    retirer les 4 ne laisse qu'une répétition.
    Si on supprime toutes les occurrences du nombre 4, il reste une seule répétition. Il n'est pas possible d'en obtenir moins, donc votre programme doit afficher :

    1
    Limites
    Limite de temps : 1000 ms.

    Limite de mémoire : 64000 kb.

    La limite de temps est réglée de telle sorte qu'une solution qui parcourt un petit nombre de fois toute la liste puisse avoir tous les points, mais qu'une solution qui pour chaque nombre de la liste, boucle sur tous les autres nombres de la liste ne puisse résoudre qu'environ la moitié des tests sans dépasser la limite de temps.


    et voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    nb = int(input())
    lst = []
    dico = {}
    for i in range(nb):
        lst.append(int(input()))
    for val in lst:
        dico[val] = 0
     
    for i in range(1, nb):
        nombre = lst[i]
        if nombre == lst[i-1]:
            for key in dico:
                if key != nombre:
                    dico[key] += 1
        else :
            det = 2
            nombretre = lst[i-1]
            Trouve = False
            while Trouve == False and det <= i :
                if nombre == lst[i-det] :
                    dico[nombretre] += 1
                    Trouve = True
                if lst[i-det] != nombretre:
                    Trouve = True
                det += 1
     
    print(min(dico.values()))
    Avec ce code je valide 12/16 test et les 4 test m'affiche temps d'exécution dépassé comment je pourrait améliorait mon Code

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    juillet 2006
    Messages
    3 424
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Alimentation

    Informations forums :
    Inscription : juillet 2006
    Messages : 3 424
    Points : 6 249
    Points
    6 249
    Par défaut
    Bonjour,

    Tu as 3 boucles, je pense qu'avec un petit effort il est possible de passer à 2 boucles pour optimiser.

    EDIT : Mal lu, mais il y en a même plus que 3, il y en a beaucoup trop ! À la vue de ton problème, on pourrait diminuer l'ensemble à deux boucles minimum...
    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)

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    juin 2008
    Messages
    20 780
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : juin 2008
    Messages : 20 780
    Points : 35 872
    Points
    35 872
    Par défaut
    Citation Envoyé par LePauvreMiller Voir le message
    salut je suis maintenant bloqué sur exercice depuis 2 3 jours j'arrive a résoudre le problème mais je ne valide pas tous les test car mon programme est trop lent je n'arrive a trouver une solution pour le rendre plus rapide je viens donc demander conseil
    Pour aller plus vite, il faut faire moins d'opérations et le nombre d'opération dépend de l'algorithme retenu.

    Celui ci se décrit en français et sa durée dépendra de sa complexité.
    Après on le traduira éventuellement en Python et on pourra rencontrer des soucis (et demander de l'aide).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    12 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 12 131
    Points : 29 590
    Points
    29 590
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par LePauvreMiller Voir le message
    Avec ce code je valide 12/16 test et les 4 test m'affiche temps d'exécution dépassé comment je pourrait améliorer mon Code
    Peut-être en décomposant le travail
    1) écrire une fonction qui, à une liste de nombres, retourne le nb de répétitions.
    2) essayer cette fonction sur chaque sous-liste générée à partir de la liste initiale à laquelle on aurait retiré un de ses nombres
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    juin 2023
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 16
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : juin 2023
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Bonjour ...
    enfaite j'ai déjà essayé cette méthode c'était la première a la quelle j'ai pensé mais encore une fois le code étais trop lent

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    12 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 12 131
    Points : 29 590
    Points
    29 590
    Billets dans le blog
    1
    Par défaut
    Mouais je m'en doutais. C'est l'algorithme "brute force" et si un brute force fonctionne toujours, c'est aussi toujours le plus lent.

    Voici ce à quoi je pense: il faut retirer le chiffre présent le plus grand nombre de fois, à condition que
    • ce chiffre soit déjà répété (ça supprime au-moins une répétition)
    • cette répétition ne soit pas encadrée de deux chiffres identiques (sinon ça les rapproche et recrée une répétition remplaçant celle qu'on supprime)

    Je pense qu'on doit pouvoir trouver le chiffre répondant à ces critères en un seul parcours de liste.

    PS: c'est plus un souci d'algo que de Python. Exemple: si tu dois aller de A à B en voiture X, tu iras regarder sur une carte de la région, pas dans la notice de ta voiture.

    J'ai réussi un algo qui effectivement traite en une passe, et qui sort les bonnes valeurs pour les 2 jeux d'essais de ce topic. Pour 1 3 2 2 3 4 4 2 1 il sort "4" et pour 1 3 3 4 2 2 1 1 1 il sort "1"
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #!/usr/bin/env python3
    # coding: utf-8
     
    liste=(1, 3, 2, 2, 3, 4, 4, 2, 1)
    #liste=(1, 3, 3, 4, 2, 2, 1, 1, 1)
    #liste=(1, 4, 4, 4, 4, 1)
     
    recap={
    	liste[0]: {"value" : liste[0], "cpt" : 1, "bord": 0, "repeat": 0},
    }
    for i in range(1, len(liste)):
    	l=liste[i]
    	if l not in recap:
    		recap[l]={"value" : l, "cpt" : 1, "bord": 0, "repeat" : 0}
    		continue
    	# if
    	recap[l]["cpt"]+=1
    	if l == liste[i-1]:
    		recap[l]["repeat"]+=1
    		try:
    			if liste[i-2] == liste[i+1]:
    				recap[l]["bord"]+=1
    		except IndexError: pass
    # for
    print(tuple(sorted(recap.values(), key=lambda x: (x["repeat"], -x["bord"], x["cpt"]), reverse=True))[0]["value"])
    Je l'ai un peu modifié par rapport à l'idée de départ (à savoir pas de bord et répétition obligatoire) car ça l'empêche de trouver un résultat dans 1 4 4 4 4 1 (il n'y a qu'une répétition et elle a une bordure).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    mai 2006
    Messages
    709
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : mai 2006
    Messages : 709
    Points : 1 824
    Points
    1 824
    Par défaut
    J'aime bien cet exercice car il pose des contraintes qui obligent à penser performance (et donc forcément algorithmique et manière de faire).

    Une suggestion: ajouter des éléments à une liste via append a un coût. Normalement, en Python, on ne s'amuserait pas à alimenter une liste ou en retirer des éléments à répétition. Au lieu de ça, on utilisera un list compréhension ou un générateur.
    Votre stratégie sera pénalisante si vous avez des boucles avec un nombre importants d'itérations.

    Tout ça peut se mesurer. Je vous invite à le faire sur les différentes parties de votre code, ainsi vous verrez mieux les goulets d'étranglement. Il y a par exemple le module timeit qui est là pour ça. Personnellement j'aime bien le module codetiming (dispo via PIP). Un article qui détaille son fonctionnement: https://realpython.com/python-timer/

    L'intérêt d'un générateur, c'est qu'il peut être consommé au fur et à mesure, au contraire d'une liste qui doit être entièrement construite avant de pouvoir être récupérée. Je ne sais pas si vous avez explosé la limite de RAM qui était impartie mais je pense que cette contrainte n'est pas innocente.

    Pour résumer: si vous produisez des listes volumineuses, ou les modifiez de manière répétée, vous avez un problème de design.

    Accessoirement, il y a des trucs pas très Pythonic:
    Plus besoin si vous êtes en Python3.

    Ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i in range(1, len(liste)):
    peut tout simplement s'écrire:
    Mais dans le cas où vous avez besoin d'une valeur i incrémentée, alors vous pouvez utilisez la fonction enumerate:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i, item in enumerate(liste, start=1):
    Et donc vous constaterez que ce genre de truc n'a pas de sens:
    D'accord, c'est pas vraiment le problème dans le cas présent, mais ça améliore la lisibilité, ce qui n'est pas négligeable quand on tâtonne avec l’algorithmique.

    Ce qui me dérange, c'est que vous créez un dict recap, tout en continuant d'utiliser une liste en parallèle. A la rigueur, je comprendrais que vous transformiez l'objet d'origine pour l'enrichir, mais vous vous dispersez en regardant à gauche et à droite. De toute façon, vous avez déjà trop de variables inutiles comme i et l, que l'on peut facilement confondre par ailleurs. J'insiste sur la lisibilité du code, qui est le prérequis pour qu'il soit compréhensible.

    Un dernier mot:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    except (IndexError, KeyError):
    Si vous avez des exceptions ne les passez jamais sous silence, à moins de savoir ce que vous faites. Car vous masquez des erreurs potentielles et rendez d'éventuels bugs invisibles.
    En principe, vous ne devriez pas avoir ces erreurs. Sinon, cela indique des erreurs de logique qui doivent être identifiées et corrigées, mais pas glissées sous le tapis

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    12 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 12 131
    Points : 29 590
    Points
    29 590
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par binarygirl Voir le message
    Plus besoin si vous êtes en Python3.
    Explicite vaut mieux qu'implicite (pep 203)

    Citation Envoyé par binarygirl Voir le message
    Ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i in range(1, len(liste)):
    peut tout simplement s'écrire:
    Non? vraiment???
    J'ai besoin d'un indice parce que je vais regarder des éléments placés en amont ou en aval de la liste. Et je commence au second élément pour pouvoir comparer avec le premier s'ils forment une répétition (le premier, ne pouvant pas former une répétition avec son précédent inexistant, n'a pas besoin d'être traité). Or je n'aurai rien de tout ça avec le for.

    Citation Envoyé par binarygirl Voir le message
    Mais dans le cas où vous avez besoin d'une valeur i incrémentée, alors vous pouvez utilisez la fonction enumerate:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i, item in enumerate(liste, start=1):
    Ce qui démarre l'énumération au premier élément alors que moi je veux commencer au second!!!
    Ok on peut écrire for (i, item) in enumerate(liste[1:], start=1): (et avec des parenthèses pour expliciter le tuple ce qui améliorera la lisibilité) mais je n'y ai pas pensé sur le moment.

    Citation Envoyé par binarygirl Voir le message
    Et donc vous constaterez que ce genre de truc n'a pas de sens:
    C'était pour éviter les répétitions multiples recap[liste[i]] qui me gonflaient

    Citation Envoyé par binarygirl Voir le message
    Ce qui me dérange, c'est que vous créez un dict recap, tout en continuant d'utiliser une liste en parallèle. A la rigueur, je comprendrais que vous transformiez l'objet d'origine pour l'enrichir,
    Je ne "continue" pas d'utiliser une liste en parallèle, je lis la liste une et une seule fois pour en extraire des infos que je stocke au fur et à mesure dans un dictionnaire récapitulatif (d'où le nom "recap"). Ainsi, à la fin de l'unique boucle sur la liste, recap contient tout ce dont j'ai besoin pour en extraire le nombre à trouver. Evidemment cette extraction nécessite un tri (ce qui se traduit là par encore des boucles cachées) mais j'ai l'espoir et en l'algo de tri (qsort?) et en le code de sorted qui doit probablement être écrit en C.

    Citation Envoyé par binarygirl Voir le message
    mais vous vous dispersez en regardant à gauche et à droite.
    Oui, car j'ai besoin de regarder les chiffres placés avant et après le couple trouvé.

    Citation Envoyé par binarygirl Voir le message
    De toute façon, vous avez déjà trop de variables inutiles comme i et l
    l peut-être (c'est juste un raccourci vers liste[l] et effectivement un raccourci n'est pas obligatoire).
    i non j'en ai besoin!!!

    Citation Envoyé par binarygirl Voir le message
    Un dernier mot:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    except (IndexError, KeyError):
    Si vous avez des exceptions ne les passez jamais sous silence, à moins de savoir ce que vous faites. Car vous masquez des erreurs potentielles et rendez d'éventuels bugs invisibles.
    Justement je sais ce que je fais (la preuve je les ai nommées ces exceptions là où d'autres auraient écrit, comme je le vois très souvent, except: pass). Ca m'évite de devoir checker si je suis arrivé trop au bord.

    Citation Envoyé par binarygirl Voir le message
    En principe, vous ne devriez pas avoir ces erreurs. Sinon, cela indique des erreurs de logique qui doivent être identifiées et corrigées, mais pas glissées sous le tapis
    Non, si vous aviez suivi l'idée exprimée en début de post, vous auriez vu que pour chaque élément qui fait partie d'une répétition on doit examiner les chiffres situés avant et après la répétition. Fatalement il peut arriver que le chiffre examiné ne soit pas encore dans recap (KeyError) ou que je sois trop au bord pour avoir un chiffre à examiner (IndexError). L'autre solution eut été de tester ces éventualités mais bon, je voulais juste vérifier le proof of concept de mes idées et donc pondu rapidement ce code jeté ensuite après usage.
    Alors effectivement on peut faire les mêmes examens avec liste[i] plutôt que recap[liste[i]] (car ils contiennent la même valeur) donc le KeyError peut sauter.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    juillet 2006
    Messages
    3 424
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Alimentation

    Informations forums :
    Inscription : juillet 2006
    Messages : 3 424
    Points : 6 249
    Points
    6 249
    Par défaut
    Hello,

    Tout ça pour dire que c'est un exercice d'algorithmie et que l'objectif est que les tests passent, pythonic ou pas...

    Une fois les tests passés, on peut regarder si c'est beau ou moche, mais actuellement la question se pose pas.

    @Sve@r,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print(tuple(sorted(recap.values(), key=lambda x: (x["repeat"], -x["bord"], x["cpt"]), reverse=True))[0]["value"])
    Qu'apporte tuple dans cette ligne ?

    -------------------

    Pour éviter pass dans les blocs try - except, on peut utiliser suppress du module contextlib.

    @binarygirl

    Je suis curieux de savoir pourquoi liste[i] n'a pas de sens, peux-tu expliquer ? L'utilisation des index sur des listes est assez courante... quelle solution proposes-tu autres que range(len(...)) dans cette situation et en t'appuyant sur le code de Sve@r ?
    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)

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    12 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 12 131
    Points : 29 590
    Points
    29 590
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Qu'apporte tuple dans cette ligne ?
    Ah ben oui, ça marche sans!!! Désolé de l'avoir mis, effectivement ça sert à rien.
    En fait, généralement les générateurs comme map(), filter() et autres renvoient un iterable. Pour avoir leur contenu, soit on itère dessus, soit on les met en tuple. Exemple:
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> print(map(int, "12345"))
    <map object at 0x7f135b06b490>
    >>> print(tuple(map(int, "12345")))
    (1, 2, 3, 4, 5)

    Et j'ai donc appliqué ce principe sur sorted() pensant que ce serait la même chose sans le vérifier

    Citation Envoyé par fred1599 Voir le message
    Je suis curieux de savoir pourquoi liste[i] n'a pas de sens
    En fait elle n'a pas dit que liste[i] n'avait pas de sens ; mais que c'était l=liste[i] qui n'avait pas de sens. C'est vrai que ça n'a pas de sens de copier x dans y sans transformation ni de x ni de y. Sauf que dans ce cas précis (exception qui confirme la règle?) c'était pour simplifier l'écriture du reste du code qui faisait plusieurs fois appel à liste[i] dans des écritures assez lourdes.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  11. #11
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    juillet 2006
    Messages
    3 424
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Alimentation

    Informations forums :
    Inscription : juillet 2006
    Messages : 3 424
    Points : 6 249
    Points
    6 249
    Par défaut
    Désolé de l'avoir mis, effectivement ça sert à rien.
    Pas de soucis, c'est pas un reproche, mon objectif est de parler techniquement de la solution (faire réfléchir sur ...), pas d'imposer

    Concernant le sujet l = liste[i], @binarygirl confirmera sans doute... Cependant pourquoi l qui est une variable qui même si pas conseillée est le nom raccourci d'un objet list ? Peut-être current_value et precedent_value pour la valeur à l'index précédent était plus adapté ?

    Autre question que je me pose, c'est pourquoi utiliser une clé value dans le dictionnaire recap[value] si cette valeur est identique ? Ne peut-on pas utiliser la clé de recap, plutôt que recap[value]["value"] ?
    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)

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    12 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 12 131
    Points : 29 590
    Points
    29 590
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Pas de soucis, c'est pas un reproche, mon objectif est de parler techniquement de la solution (faire réfléchir sur ...), pas d'imposer
    Sisi moi je m'en fais le reproche à moi-même. Si j'avais testé j'aurais vu que ça fonctionne directement. Je veux dire que si la situation était inversée, je ne me serais pas gêné pour le dire que que tuple() est inutile. Et j'aime pas les trucs inutiles tout autant chez-moi que chez les autres

    Citation Envoyé par fred1599 Voir le message
    Autre question que je me pose, c'est pourquoi utiliser une clé value dans le dictionnaire recap[value] si cette valeur est identique ? Ne peut-on pas utiliser la clé de recap, plutôt que recap[value]["value"] ?
    Pareil, là c'est aussi un résultat de l'effet "code créé à l'arrache" (hier soir 22h quoi). Au début les éléments du dictionnaire ne contenaient pas la clef "value". La valeur de l'élément [i] de la liste me servait juste de clef de recap pour pouvoir associer à cet élément des informations comme "combien de fois on le trouve" ou "a-t-il des bords" etc.
    Puis à l'affichage, je me suis rendu compte qu'il me fallait aussi afficher ladite valeur, valeur qui ne se trouve que dans la clef et pas dans le champ "values()" du dictionnaire "recap". D'où le rajout ensuite de cette même valeur en plus, juste pour pouvoir l'afficher au final.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  13. #13
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    juillet 2006
    Messages
    3 424
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Alimentation

    Informations forums :
    Inscription : juillet 2006
    Messages : 3 424
    Points : 6 249
    Points
    6 249
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Pareil, là c'est aussi un résultat de l'effet "code créé à l'arrache" (hier soir 22h quoi). Au début les éléments du dictionnaire ne contenaient pas la clef "value". La valeur de l'élément [i] de la liste me servait juste de clef de recap pour pouvoir associer à cet élément des informations comme "combien de fois on le trouve" ou "a-t-il des bords" etc.
    Puis à l'affichage, je me suis rendu compte qu'il me fallait aussi afficher ladite valeur, valeur qui ne se trouve que dans la clef et pas dans le champ "values()" du dictionnaire "recap". D'où le rajout ensuite de cette même valeur en plus, juste pour pouvoir l'afficher au final.
    Ok ! En testant ton code, je trouve 4 pour la liste 1 3 2 2 3 4 4 2 1, cette valeur représente bien le nombre minimum de répétitions possibles ?

    Si je retire les 4, il ne me reste plus qu'une répétition de 2, j'ai peut-être pas bien compris l'énoncé, mais je dirai que le résultat à trouver devrait être 1, non ?
    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)

  14. #14
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    12 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 12 131
    Points : 29 590
    Points
    29 590
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    j'ai peut-être pas bien compris l'énoncé, mais je dirai que le résultat à trouver devrait être 1, non ?
    En fait, avec 1 3 2 2 3 4 4 2 1 il y a 2 répétitions
    • le couple 2 2
    • le couple 4 4

    L'énoncé est "quel chiffre retirer pour avoir au final le nombre de répétitions le plus bas" (sous-entendu que si on retire le chiffre "x" on retire toutes les occurrences de ce "x")

    Si on retire les 1, cela ne change rien, il y aura toujours répétitions des 2 et des 4 (2 reps)
    Si on retire les 2, cela donne la liste 1 3 3 4 4 2 1 et bien qu'ayant supprimé la répétition des 2, on se retrouve à la place avec reps de 3 et reps de 4 (2 reps)
    Si on retire les 3, cela ne change rien, il y aura toujours répétitions des 2 et des 4 (2 reps)
    Si on retire les 4, cela donne la liste 1 3 2 2 3 2 1 et là il n'y a plus qu'une seule répétition (celle des 2)
    => Faut retirer les 4.

    D'où mon idée de départ : ne se concentrer que sur les chiffres qui déjà forment une répétition, en checkant aussi les chiffres situés en bordure car si ce sont les mêmes, en se rapprochant ils recréent une répétition.
    Ensuite viennent les cas particuliers comme 1 4 4 4 4 1. Il y a des "1" identiques en bordure des 4 mais là ça va quand-même car on supprime 3 répétitions (les répétitions ne se prennent que 2 par 2 donc avec "4 4 4 4" ça fait bien 3 répétitions) pour en créer une et autres cas tout aussi tordus (que j'ai pas vérifiés)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    juillet 2006
    Messages
    3 424
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Alimentation

    Informations forums :
    Inscription : juillet 2006
    Messages : 3 424
    Points : 6 249
    Points
    6 249
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    En fait, avec 1 3 2 2 3 4 4 2 1 il y a 2 répétitions
    • le couple 2 2
    • le couple 4 4

    L'énoncé est "quel chiffre retirer pour avoir au final le nombre de répétitions le plus bas" (sous-entendu que si on retire le chiffre "x" on retire toutes les occurrences de ce "x")

    Si on retire les 1, cela ne change rien, il y aura toujours répétitions des 2 et des 4 (2 reps)
    Si on retire les 2, cela donne la liste 1 3 3 4 4 2 1 et bien qu'ayant supprimé la répétition des 2, on se retrouve à la place avec reps de 3 et reps de 4 (2 reps)
    Si on retire les 3, cela ne change rien, il y aura toujours répétitions des 2 et des 4 (2 reps)
    Si on retire les 4, cela donne la liste 1 3 2 2 3 2 1 et là il n'y a plus qu'une seule répétition (celle des 2)
    => Faut retirer les 4.

    D'où mon idée de départ : ne se concentrer que sur les chiffres qui déjà forment une répétition, en checkant aussi les chiffres situés en bordure car si ce sont les mêmes, en se rapprochant ils recréent une répétition.
    Ensuite viennent les cas particuliers comme 1 4 4 4 4 1. Il y a des "1" identiques en bordure des 4 mais là ça va quand-même car on supprime 3 répétitions (les répétitions ne se prennent que 2 par 2 donc avec "4 4 4 4" ça fait bien 3 répétitions) pour en créer une et autres cas tout aussi tordus (que j'ai pas vérifiés)...
    Je pensais bien que tu avais compris comme cela et c'est correct à mon sens, mais ce que dit le PO et son énoncé:

    Si on supprime toutes les occurrences du nombre 4, il reste une seule répétition. Il n'est pas possible d'en obtenir moins, donc votre programme doit afficher :

    1
    Je pense que l'incompréhension est dans l'oubli d'une ligne pour afficher ceci, qu'est-ce que tu en penses ?
    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)

  16. #16
    Membre chevronné
    Profil pro
    Inscrit en
    mai 2006
    Messages
    709
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : mai 2006
    Messages : 709
    Points : 1 824
    Points
    1 824
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Concernant le sujet l = liste[i], @binarygirl confirmera sans doute... Cependant pourquoi l qui est une variable qui même si pas conseillée est le nom raccourci d'un objet list ? Peut-être current_value et precedent_value pour la valeur à l'index précédent était plus adapté ?
    Ce serait effectivement une amélioration qui rendrait le code plus lisible et plus intuitif, et surtout qui ne coûte rien. J'ai insisté sur ce point d'autant plus que i et l (et 1...) se ressemblent très fort, ce qui est de nature à augmenter le risque de confusion et donc de bugs. Je précise que mes commentaires ne s'adressaient pas à Sve@r (je réfléchirais bien avant de le critiquer ), mais je commentais le code d'origine même s'il l'a repris en bonne partie.

    Comme notre ami est lycéen et que je considère cette tâche comme un devoir, je n'ai pas cherché à donner une solution immédiatement, au lieu de cela je me suis bornée à proposer des améliorations marginales à la version actuelle.

    Je vois pas mal d'approches possibles, par exemple détecter les répétitions consécutives devrait être facile avec itertools.groupby

    Exemple:
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    from itertools import groupby
     
    liste = (1, 3, 2, 2, 3, 4, 4, 2, 1)
    for key, occurrences in groupby(liste):
        print(f"key: {key} - occurrences: {list(occurrences)}")

    Résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    key: 1 - occurrences: [1]
    key: 3 - occurrences: [3]
    key: 2 - occurrences: [2, 2]
    key: 3 - occurrences: [3]
    key: 4 - occurrences: [4, 4]
    key: 2 - occurrences: [2]
    key: 1 - occurrences: [1]
    Ça peut être un point de départ pour décomposer la liste de départ efficacement, et la traiter plus facilement.

    L'exercice n'interdit rien a priori, donc on peut trouver des approches plus farfelues mais je ne sais pas si @LePauvreMiller a déjà appris à utiliser le module itertools dans le cadre de sa formation. C'est peut-être trop avancé pour l'instant, ou pas assez.

  17. #17
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    12 131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : février 2006
    Messages : 12 131
    Points : 29 590
    Points
    29 590
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Je pense que l'incompréhension est dans l'oubli d'une ligne pour afficher ceci, qu'est-ce que tu en penses ?
    Ah zut!!! Le truc ne doit pas afficher le nombre qu'on retire (enfin pas que) mais le nombre de répétitions restantes !!!
    Ok j'ai aussi raté ça

    Bon, hier c'était pas ma soirée (ou juin c'est pas mon mois ou 2023 c'est pas mon année, c'est comme tu le sens )

    Citation Envoyé par binarygirl Voir le message
    Je ne sais pas si @LePauvreMiller a déjà appris à utiliser le module itertools dans le cadre de sa formation. C'est peut-être trop avancé pour l'instant, ou pas assez.
    C'est souvent un souci (et pour l'élève, et pour le professeur).
    L'élève a-t-il le droit d'utiliser des outils déjà existants?
    D'un côté le but d'un exercice est d'apprendre à trouver ses algos pour solutionner des problèmes, mais d'un autre côté quand il sera IRL il aura ces outils à sa disposition donc pourquoi s'embêter à réécrire la roue? Oui mais peut-être IRL il ne codera pas en Python donc n'aura pas ces outils dispos...
    Je pense qu'il n'y a pas de réponse simple à cette problématique...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  18. #18
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    juillet 2006
    Messages
    3 424
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Alimentation

    Informations forums :
    Inscription : juillet 2006
    Messages : 3 424
    Points : 6 249
    Points
    6 249
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ah zut!!! Le truc ne doit pas afficher le nombre qu'on retire (enfin pas que) mais le nombre de répétitions restantes !!!
    Ok j'ai aussi raté ça

    Bon, hier c'était pas ma soirée (ou juin c'est pas mon mois ou 2023 c'est pas mon année, c'est comme tu le sens )
    Le PO a été suffisamment guidé pour s'en sortir, que se soit dans la compréhension du problème que dans la syntaxe Python.
    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)

  19. #19
    Candidat au Club
    Homme Profil pro
    Lycéen
    Inscrit en
    juin 2023
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 16
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : juin 2023
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    merci au personne qui ont envoyé des message et des conseil car en piochant un peu dans les réponses de tout le monde et avec un peu de logique j'ai réussi a passer tout les test de l'exercice dans les limites de temps imposé par l'énoncé franchement merci de l'aide c'est super sympas

    mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    nbNombres = int(input())
    nombres = [int(input()) for _ in range(nbNombres)]
     
    paires = {}
    for i in range(nbNombres - 1):
        if nombres[i] == nombres[i+1]:
            if nombres[i] in paires:
                paires[nombres[i]] += 1
            else:
                paires[nombres[i]] = 1
     
    min_paires = float('inf')
    for nombre, occ in paires.items():
        liste_sans_nombre = [x for x in nombres if x != nombre]
     
        paires_supprimees = 0
        for i in range(len(liste_sans_nombre) - 1):
            if liste_sans_nombre[i] == liste_sans_nombre[i+1]:
                paires_supprimees += 1
     
        min_paires = min(min_paires, paires_supprimees)
     
    print(min_paires)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Python 2.X] Besoin d'aide sur un de mes programmes
    Par Delta935 dans le forum Général Python
    Réponses: 13
    Dernier message: 22/04/2019, 18h26
  2. Besoin d'aide sur python, exercices sur les fichiers
    Par Mini-minimoys dans le forum Général Python
    Réponses: 6
    Dernier message: 21/11/2015, 18h37
  3. Besoin d'aide sur un exercice en POO
    Par scriptkiddie dans le forum Débuter
    Réponses: 4
    Dernier message: 24/06/2013, 09h56
  4. besoin d aide sur un exercice sur les pointeurs
    Par azumachakib69 dans le forum C
    Réponses: 3
    Dernier message: 28/12/2006, 01h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo