Nombres à 5 chiffres — Les-maths.net The most powerful custom community solution in the world

Nombres à 5 chiffres

Modifié (21 Nov) dans Combinatoire et Graphes
Bonjour
Un exercice du concours kangourou 2021 dont je ne dispose pas de solution. Ma réponse est-elle correcte ? 

Soit un nombre entier naturel dont les chiffres, lus de gauche à droite, augmentent d'abord puis diminuent (2 chiffres adjacents n'étant jamais égaux). 
Combien existe-t-il de nombres de la sorte à cinq chiffres dont la somme des chiffres est $9$ ? 

Mon raisonnement.
Le premier chiffres est inférieur ou égal à 7 forcément. Il y  a donc 8 choix (de 0 à 7)
Pour le deuxième chiffre, il doit être strictement supérieur ou premier, il y a donc 7 choix.
Pour le troisième chiffre, il y a 6 choix.
Pour les quatrièmes et cinquième chiffre, ils sont égaux aux second et premier donc 1 choix.
Au total, il y a $8 \times 7 \times 6 \times 1 \times 1 =336 $ possibilités.

Je cherche maintenant les nombres de la sorte tels que la somme des chiffres est $9$.
Le premier chiffre est forcément strictement inférieur à $2$, sinon on aurait $2+3+4+3+2 >9$. Le premier chiffre est donc 0 ou 1.
Le deuxième chiffre est strictement inférieur à 3 sinon c'est impossible. Il vaut  2 sinon la somme des chiffres est trop petite. Il ne peut pas valoir 0 car il est supérieur au premier.
Le troisième chiffre est strictement  inférieur à 4 sinon c'est impossible. Il vaut forcément 2 ou 3 car il est supérieur au deux premiers chiffres. 

Le nombre $\boxed{1 2 3 2 1}$ convient et c'est l'unique possibilité.

Réponses

  • Un nombre à 5 chiffres qui commence par un zéro ne s'appelle-t-il pas un nombre à 4 chiffres ? 
  • J'ai au moins 14310 qui fonctionne aussi.
    Et un autre qui commence par 2 que je te laisse trouver.
  • Oui c'est  vrai bien vu.

    Je crois que j'ai mal compris l'énoncé, le chiffre du milieu est quelconque ? Il peut être égal au deuxième chiffre ou au quatrième ? 

  • L'énoncé te dis "ça augmente puis ça diminue".
    Il ne dit pas qu'il y a une symétrie dans les variations.
  • Modifié (21 Nov)
    def les_bons():
        bons = []
        for n in range(10000, 100000):
            a,b,c,d,e = [int(i) for i in str(n)]
            if sum((a,b,c,d,e)) == 9 and b > a and d > e and (c > b or (c < b and c > d)):
                bons.append(n)
        return bons
    C'est pas de la tarte pour arriver à écrire du code correctement dans le nouveau forum.
  • Modifié (28 Nov)
    Le premier chiffres est inférieur ou égal à 7 forcément. Il y  a donc 8 choix (de 0 à 7)
    Pour le deuxième chiffre, il doit être strictement supérieur ou premier, il y a donc 7 choix.
    hum hum
    Pour le troisième chiffre, il y a 6 choix.
    à nouveau hum hum !

    Tu calcules un 336 qui est totalement faux.  Premier mauvais point.  Même avec la symétrie que tu ajoutes à l'énoncé, même en considérant qu'un nombre de 5 chiffres peut commencer par 0, c'est faux.
    Et tu ne t'aperçois même pas que ce résultat de 336 ne te sert à rien dans la suite de ton raisonnement. Deuxième mauvais point.

    Correction du code de @bisam,  trop de cas étaient pris en compte.
    <code><div></div><pre class="CodeBlock"><code><div>def les_bons():</div><div>&nbsp; &nbsp; bons = []</div><div>&nbsp; &nbsp; for n in range(10000, 100000):</div><div>&nbsp; &nbsp; &nbsp; &nbsp; a,b,c,d,e = [int(i) for i in str(n)]</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if sum((a,b,c,d,e)) == 9 and b > a and d > e:&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( c>b and c>d ) or ( b >c and c> d ) or (b<c and c <d ):</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bons.append(n)</div><div>&nbsp; &nbsp; return bons</div><div>&nbsp; &nbsp;&nbsp;</div><div>print ( les_bons())</div>


    [@lourrran : je ne suis pas arrivé à présenter correctement ce code python. :) AD]
  • Effectivement, je crois avoir oublié d'éliminer la possibilité a<b<c=d>e.
  • Modifié (22 Nov)
    Doublon du message précédent posté par erreur suite à une erreur 504.
  • Modifié (21 Nov)
    D'accord merci. J'essaie de faire une vraie démonstration. 
    Notons le nombre recherché $xyztu$ de sorte que $x+y+z+t+u=9$
    On a d'après les conditions de l'énoncé $x<y$ et $t<u$. Ainsi, $x+y+z+t+u < 2y +z +2u $ et donc $x+y+z+t+u =9 > 2x +z+ 2t$
    Soit $\boxed{2x+z+2t < 9}$
    On sait que $0<x<4$ car sinon $x+y+z+t+u >9$. Ainsi $\boxed{x \in \{1,2,3 \}}$
    De même $\boxed{t \in \{1,2,3 \}}$ Il y a donc 9 cas possibles. 
    Après dans chaque cas, il y a plein de cas, je me perds dans un nombre incalculable de cas.
    J'ai peut être raté une astuce   :'(
  • Modifié (21 Nov)
    Tu as confondu t et u. Pas grave.
    Tu dis 3 possibilités pour x, et 3 possibilités pour u donc 9 possibilités pour (x,u)
    Oui et non.
    On peut multiplier quand ça sert à quelque chose, c'est à dire quand les 2 cases sont indépendantes.
    Quand x=3,  sachant que le total doit donner 9, x=3 consomme beaucoup d'espace, et donc limite les possibilités pour u.  
    Donc le 3x3 ne mène nulle part.

    En plus, c'est un exercice de niveau collège, tu utilises un outil que les collégiens ne connaissent pas, et qui n'est pas adapté.
    si x=3, forcément y vaut au moins 4, x+y donne 7 ou 8 ou 9, et donc z,t,u doivent être 3 chiffres, dont la somme donnerait 0 ou 1 ou 2.
    Avec les contraintes données, on ne peut pas trouver de triplet (z,t,u) qui convient.
    si x=2 et y=3 ...pas énormément de possibilités pour (z,t,u)
    si x=2 et y=4 , pareil, on trouve très vite les triplets (z,t,u) qui conviennent.
    Il y a une dizaine de cas à explorer pour le couple (x,y).  5 minutes de petits calculs.
  • D'accord merci. 

    On a forcément $y >x$ ce qui réduit les possibilités. 

    Si $x=1$ et $y=2$ alors $12051$, $12042$, $12132$,  $12321$, $12420$, $12510$ conviennent. 

    Si $x=1$ et $y=3$ alors $13032$, $13131$, $12420$, $12510$ fonctionnent.

    Si $x=1$ et $y=4$ alors $14031$, $14040$, $14121$, $14130$ fonctionnent.

    Si $x=2$ et $y=3$ alors $23040$, $23031$, $23130$, $23121$ fonctionnent.

    Si $x=2$ et $y=4$ alors $24030$, $24021$, $24120$, $24210$ fonctionnent.

    Si $x=3$ et $y=4$ alors $34020$ convient.

    Les nombres recherchés sont trop nombreux. J'ai sûrement faux  :'(
    J'ai trouvé un corrigé qui en donne que 7.


  • 12051 ne convient pas...
  • Modifié (21 Nov)
    Je ne comprends pas pourquoi 12051 ne marche pas. 

    On a des chiffres adjacents différents et $1<2$ tandis que $5>1$
  • Pffffffffff  ,  si j'étais prof et que j'avais un élève comme toi, je démissionnerais tout de suite.

    Soit un nombre entier naturel dont les chiffres, lus de gauche à droite, augmentent d'abord puis diminuent .

    Augmentent , puis diminuent...  Dans ta 1ère réponse, tu avais su traduire ça correctement, mais tu faisais des calculs faux, sans aucun intérêt.
    Maintenant, tu ne peux plus te tromper sur les calculs car on t'a tout dit, mais tu ne comprends plus l'énoncé de l'exercice !



  • Ok merci.

    Il reste donc 12321, 12420, 12510, 24210. Et j'en ai oublié, j'ai aussi oublié le cas $x=1$, $y=5$ :

    Il me manque 13410, 14310, 15210, 

    Finalement il y 7 nombres recherchés.

    Le problème est que j'avais mal compris l'énoncé  :( 
  • Modifié (28 Nov)
    J’en trouve 14.
    #!/usr/bin/python3
    
    from itertools import product
    signe=lambda x: x and (1, -1)[x<0]
    
    l=[]
    for n in product("0123456789",repeat=5):
      p=[signe(int(n[i])-int(n[i+1])) for i in range(4)]
      if p[0]>=0 or p[-1]<=0 or sum(map(int,n))!=10 or n[0]=="0":
        continue
      while p and p[0]==-1:
        del p[0]
      while p and p[-1]==1:
        del p[-1]
      if not p:
        l.append("".join(n))
    print(len(l),*l)
    Réponse :
    14 12340 12421 12430 12520 12610 13420 13510 14320 15310 16210 23410 24310 25210 34210

    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • La somme doit faire 9, et non 10 !
    #R
    p<-function(){
    for(a in 1:8){for(b in (a+1):9){for(c in 0:9){
    for(d in 1:9){for(e in 0:(d-1)){if(a+b+c+d+e==9){
    if(b>c && c>d){print(10000*a+1000*b+100*c+10*d+e)}
    if(b<c && c>d){print(10000*a+1000*b+100*c+10*d+e)}
    if(b<c && c<d){print(10000*a+1000*b+100*c+10*d+e)}}}}}}}}
    
    > p()
    [1] 12321
    [1] 12420
    [1] 12510
    [1] 13410
    [1] 14310
    [1] 15210
    [1] 24210
  • Modifié (22 Nov)
    Dans ce cas j’en trouve sept :
    7 12321 12420 12510 13410 14310 15210 24210
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Modifié (22 Nov)
    Le code de Zgrb m'a l'air compréhensible et efficace. Il y a bien 3 cas à distinguer pour le chiffre du milieu. 
    L'instruction p<-function() sert à quoi ? Pourquoi le résultat final affiche des [1] ? 
    Je ne trouve rien sur le net pour function()

    Par contre Nicolas Patrois, ton code je n'ai pas bien compris. 
    Rien que la première ligne je ne comprends pas ce que fait : signe=lambda x: x and (1, -1)[x<0]
    C'est quoi p[-1]
  • Le code de Zgrb n’est pas du Python.
    Le mot clé lambda permet de fabriquer une fonction anonyme, sauf qu’ici, je la nomme signe parce que oui, il n’y a pas de fonction signe en Python (à part dans numpy). As-tu essayé de jouer avec cette fonction ?
    p[-1] est le dernier élément de l’itérable p.
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Modifié (22 Nov)
    Bonjour,

    p<-function()  définit une fonction et l'appelle p.

    Comme son nom l'indique  signe=lambda x: x and (1, -1)[x<0] définit la fonction signe d'un nombre, c'est à dire +1 si x>0, 0 si x=0 et -1 si x<0.    p[-1] est le dernier terme de la liste p.
    Si tu ne connais pas Python, il te faut d'abord l'apprendre.
    Ensuite, taper "Python lambda" dans google devrait être à ta portée.
    Tu aurais d'ailleurs pu tester signe(x) dans n'importe quel environnement Python avec diverses valeurs de x.

    Cordialement,
    Rescassol

  • Modifié (22 Nov)
    Un peu tirée par les cheveux la fonction signe !
    signe = lambda x : 0 if x==0 else x//abs(x)
  • x/abs(x) est un flottant !
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Corrigé ! 
  • À mon avis, une division est plus coûteuse qu’une inégalité mais avec Python, on peut avoir des surprises.
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • C'est du R en effet.
    Tu peux apprendre en autodidacte, il y a plein de bons sites pour cela, google t'aidera à en trouver. Après si tu ne fais pas de stats, je te conseille de plutôt diriger tes efforts vers Python.
  • Je ne fais pas de stats ok merci. Je prendrai un livre sur Python j'arrive mieux à apprendre sur des livres.
  • J'ai donné l'exercice à mon fils, en CE2.
    Il a trouvé 12321 en 30s, puis 12420 à peine 30s plus tard et en 5 minutes il a trouvé les 5 autres et était même capable de m'expliquer qu'il ne pouvait pas y en avoir d'autres.
  • Modifié (23 Nov)
    Bisam c'est peut-être un surdoué.
    Je doute que mes élèves de 4ème 3ème le réussissent même en devoir maison.
    J'ai compris comment définir une fonction lambda (j'ai recherché) mais je ne comprends pas la syntaxe  x and (1, -1)[x<0?
    Je ne trouve rien sur internet en tapant ce passage du code. Je dois chercher quoi comme notion pour le comprendre ?
  • Modifié (23 Nov)
    Tu peux faire sans lambda avec def et return, ça merchera aussi bien.
    x and truc vaut zéro si x ou truc vaut zéro.
    (1,-1) est un couple (tuple à deux éléments), [x<0] vaut vrai ou faux (1 ou 0) selon si x<0 ou non.

    Au lieu de t’acharner à comprendre des expressions idiomatiques comme ça, écris toi-même une fonction toute simple (avec if) qui renvoie le signe.
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Modifié (23 Nov)
    C'est pas lambda qui me pose problème mais les expressions [x<0] collés avec le (1,-1) ça ne m'a pas l'air intuitif, je n'ai pas compris ton explication du
    x and (1, -1)[x<0]
    J'ai trouvé une solution simple sur le net : sign = lambda x: bool(x > 0) - bool(x < 0)
    Sinon j'ai trouvé ma propre solution, elle fonctionne je l'ai testée sur Python.
    def s(x):
      if x ==0:
        return 0 
      elif  x!=0:
        return int(x/abs(x))
  • Si tu veux comprendre le programme de Zgrb,  tu installes Python sur ton PC, ou tu utilises un site qui permet d'exécuter des programmes Python.
    Et tu joues, en écrivant des programmes de 4 lignes, puis de 5 lignes ... puis un peu plus compliqués.
    Tu regardes ce que fais cette fameuse instruction.

    Il faut mettre les mains dans le cambouis, il n'y a pas d'autre méthode.  Mais ça veut aussi dire qu'il faut réfléchir.
  • Modifié (23 Nov)
    OShine une petite code review 🤓
    def s(x):
      if x ==0:
        return 0 
      elif  x!=0:
        return int(x/abs(x))

    def s(x):
      if x == 0:
        return 0 
      return int(x/abs(x))
  • Raoul.S ça change quoi au juste ? 

    Lourrran je voulais juste savoir ce que signifie x and (1, -1)[x<0mais ça reste du chinois pour moi cette syntaxe et on ne trouve rien sur le net qui l'explique.

    Le code de Nicolas Patrois m'a l'air compliqué, je pense que Bisam a donné un code plus simple. Zgrb je comprends tout le code mais ce n'est pas du Python apparemment. 

    Bisam, que fait la dernière ligne ? Je sais que str donne une chaîne de caractères mais je n'ai pas compris la dernière ligne.
    La ligne 1 on crée une fonction.
    La ligne 2 on crée une liste vide. 
    La ligne 3 on prendre les nombres entre 10 000 et 99 000

    def les_bons():
        bons = []
        for n in range(10000, 100000):
            a,b,c,d,e = [int(i) for i in str(n)]
  • Modifié (24 Nov)
    OShine a dit :
    Lourrran je voulais juste savoir ce que signifie x and (1, -1)[x<0mais ça reste du chinois pour moi cette syntaxe et on ne trouve rien sur le net qui l'explique.
    Pourtant, je l’ai trouvée presque mot à mot sur internet.
    Essaie 0 and 4, 4 and 5, 0 or 1, etc.
    Ensuite, crée un tuple t=(2,3,4,5). Obtiens t[0], t[1], t[2]. Essaie ensuite t[True] et t[False] puis t[0<1] et t[1<0].
    Si tu veux du plus simple :
    def signe(x):
      if x==0:
        return 0
      if x<0:
        return -1
      return 1
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Bonjour,

    str(n) transforme l'entier n en une chaîne de caractères.
    Par exemple str(12345) est la chaîne '12345', c'est juste un changement de type pour pouvoir faire fonctionner le in.
    Enfin a,b,c,d,e = [int(i) for i in str(n)] met les chiffres de l'entier n dans 5 variables a,b,c,d,e

    Cordialement,
    Rescassol

  • OShine a dit :
    La ligne 3 on prendre les nombres entre 10 000 et 99 000
    Non, entre 10_000 et 99_999 (le tiret du bas est utilisable comme ça en Python).
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Rescassol merci.

    Nicolas Patrois d'accord merci. Un livre sur Python pour lycéen me permettrait d'apprendre les bases. 
  • Je conseille Python pour les kids (qui va quand même jusqu’à créer des classes) et le manuel de Gilles Dowek pour ISN, la version pour Python (trouvable en pdf sur le site de l’INRIA).
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Modifié (24 Nov)
    Bonjour
    À la conquête des maths avec Python, Peter Farrell - EYROLLES.
    Dès 14 ans.
    Cordialement,
    Rescassol

  • Tu as certainement eu des cours d'initiation à la programmation.
    Est-ce que tes bases en programmation sont plus solides ou moins solides que tes bases en mathématique ?
  • Modifié (25 Nov)
    7 [12321, 12420, 12510, 13410, 14310, 15210, 24210]
    =======================
    l = []
    r = range(10_000,99_999)
    for n in r:
        m = str(n)
        nc = len(m)
        if sum(int(c) for c in m) != 9:continue
        if any(m[i] == m[i+1] for i in range(nc-1)):continue

        trouve = False
        for j in range(1,nc-1):
            if all(m[i] < m[i+1] for i in range(0,j)) and all(m[i] > m[i+1] for i in range(j,nc-1)):
               trouve = True
               break
        if trouve:l += [n]
            
    print(len(l),l)
  • Lauret, tu peux faire sans la variable trouve !
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Modifié (28 Nov)
    OShine a dit :
    Par contre Nicolas Patrois, ton code je n'ai pas bien compris. 
    Rien que la première ligne je ne comprends pas ce que fait : signe=lambda x: x and (1, -1)[x<0]
    C'est quoi p[-1]
    Je ne suis pas très avancée en python, mais en prenant la peine et le temps d'étudier le code de Nicolas Patrois, j'ai appris des concepts nouveaux pour moi presque à chaque ligne.
  • Modifié (28 Nov)
    Celine_L et tu trouves où les explications des syntaxes ? Certaines expressions ne donnent rien en cherchant sur Google.
    Lourrran vu que je n'ai pas bossé la programmation depuis plus de 10 ans, je pense être meilleur en maths qu'en programmation.
    Étant  prof en collège, je manipule plutôt Scratch que Python. 
  • Tu copies les expressions, tu les rentres telles quelles dans un moteur de recherche, tu joues avec…
    Algebraic symbols are used when you do not know what you are talking about.
            -- Schnoebelen, Philippe
  • Modifié (28 Nov)
    OShine a dit :
    Celine_L et tu trouves où les explications des syntaxes ? Certaines expressions ne donnent rien en cherchant sur Google.
    Comme dit Nicolas Patrois, j'ouvre un notebook, je copie les expressions et je les teste avec différentes valeurs pour comprendre leur fonctionnement.
    Et disons aussi que mon premier réflexe n'est pas de me précipiter sur le forum pour dire que je n'y comprends rien. 
Connectez-vous ou Inscrivez-vous pour répondre.
Success message!