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

JavaScript Discussion :

boucle while infinie


Sujet :

JavaScript

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2017
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2017
    Messages : 166
    Points : 61
    Points
    61
    Par défaut boucle while infinie
    Bonjour,
    j'ai un tableau pour le résultat:
    divideBy = [ [], [], [0,0] ].

    J'ai un autre tableau:
    primes = [ 0, 0, 2, 3, 5, 7 ] // ne pas se préoccuper des 0, je ne m'en sert pas pour l'instant.
    Puis je vais incrémenter sur une plage de chiffres de min à max en les factorisant sur les chiffre de "primes".

    c'est à dire, en considérant min = 2 et max = 6, je vais tenter de de voir si 6 % 2 == 0, si oui, faire quelque chose. je voudrais que le code refasse ce même quelque chose tant que par exemple 6 % 2 == 0. En même temps un compteur compte le nombre de passage dans la boucle while. Enfin lorsque 6 % 2 == 1, il sortirait de la boucle en faisant un PUSH de la valeur du compteur dans le dernier tableau de divideBy.

    Pour une liste de 2 à 6 voila ce que ça donnerait au final:
    Nom : process2.JPG
Affichages : 266
Taille : 12,1 Ko

    voici mon code qui ne fonctionne pas, ou est le problème ?

    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
     let primes = [ 0, 0, 2, 3, 5, 7 ];
    let dividedBy = [[],[]]
    let compte = 0;
     
        for (let n = min; n <= max; n++) {
          dividedBy.push([0,0]);   // pour chaque n j'ajoute un nouveau sous tableau
          for (let k = 2; k <= primes.length; k++) {  
     
          while (n % primes[k] == 0) {
            let n2 = n / primes[k];
            compte += 1
            n = n2;
            k--;
          }
            dividedBy[dividedBy.length-1].push(compte)
            compte = 0
         }
        }

  2. #2
    Inactif  
    Homme Profil pro
    Webmaster
    Inscrit en
    Juin 2021
    Messages
    645
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juin 2021
    Messages : 645
    Points : 1 280
    Points
    1 280
    Par défaut
    Bonjour,

    • min et max ne sont pas définis
    • c'est for(... k < primes.length (pas <=)
    • supprime k--;.

    tu modifies n ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
          while (n % primes[k] == 0) {
            let n2 = n / primes[k];
            compte += 1
            n = n2;
    alors que n est défini dans for (let n = min; n <= max; n++).
    Pas glop.

    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
    28
    "use strict";
     
    function get_dividedBy( min=2, max=2 )
    {
      let primes = [ 0, 0, 2, 3, 5, 7 ];
      let dividedBy = [];
      let compte = 0;
     
      for( let n=min; n<=max; n++ ) 
      {
        dividedBy.push([0,0]);   // pour chaque n j'ajoute un nouveau sous tableau
        for( let k=2; k<primes.length; k++ ) 
        {  
          let n2 = n;
          while( n2 % primes[k] == 0 ) 
          {
            n2 = Number( n2 / primes[k] );
            compte++;
          }
          dividedBy[dividedBy.length-1].push(compte);
          compte = 0;
        }
      }
      return dividedBy;
    }
    /* ------------ */
    let dividedBy = get_dividedBy( 3, 17 );
    console.log( JSON.stringify(dividedBy) );

  3. #3
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Citation Envoyé par haddocks Voir le message
    J'ai un autre tableau:
    primes = [ 0, 0, 2, 3, 5, 7 ] // ne pas se préoccuper des 0, je ne m'en sert pas pour l'instant.
    Mauvaise idée, car le nom que tu donnes à ton tableau ne correspond pas à son contenu (à cause des 0 dont il ne faut pas se préoccuper justement). Tu aurais tout intérêt à avoir un tableau primes avec effectivement les nombres premiers:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const primes = [2, 3, 5, 7];
    Puis, si par la suite tu as besoin d'un tableau commençant par 0, 0 suivi des nombres premiers, tu lui trouves un nom descriptif adéquate et tu peux le composer facilement comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let nomdescriptif = [0, 0, ...primes];
    L'avantage, en plus de la clarté, c'est que tu pourras remplacer ta boucle for (let k = 2; k <= primes.length; k++) avec un 2 parachuté tout droit de l'espace, par une boucle for...of: for (const prime of primes). Ainsi dans la suite du code, plus besoin d'écrire primes[k], plus besoin de k non plus, il suffit d'écrire prime.

    Enfin lorsque 6 % 2 == 1, il sortirait de la boucle en faisant un PUSH de la valeur du compteur dans le dernier tableau de divideBy.

    Pour une liste de 2 à 6 voila ce que ça donnerait au final:
    Nom : process2.JPG
Affichages : 266
Taille : 12,1 Ko
    Au vu du résultat attendu, je pense que les conditions pour sortir de la boucle (celle sur les nombres premiers) sont plutôt:
    • soit n2 === 1 (ce qui implique que n ne sera divisible par aucun des nombres premiers suivants celui qui vient d'être testé).
    • soit lorsque le nombre premier est supérieur à n (même combat).

    Mais je reste persuadé qu'il y a une unique condition (qui regroupe les deux pré-citées) plus maline qu'il reste à trouver.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dividedBy[dividedBy.length-1].push(compte)
    Astuce: plutôt que de t'escrimer à calculer l'index du dernier élément de dividedBy pour pouvoir lui ajouter un nombre, crée un tableau temporaire dans ta boucle sur n, que tu ajoutes ensuite à dividedBy. C'est plus simple et plus lisible:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    for( let n=min; n<=max; n++ ) {
        let temp = [0, 0];
     
        for(const prime of primes) {
     
            // ...
     
            temp.push(count);
     
            if ( n2 === 1 || n < prime ) break;
        }
        dividedBy.push(temp);
    }
    (J'ai remplacé compte par count comme ça j'ai l'impression d'être super fort en anglais, tu vas voir, essaie, ça marche!)


    Autre astuce: comme tu utilises un compteur compte et une boucle while, tu peux aussi opter pour une boucle for qui se chargera d'initialiser puis d'incrémenter le compteur, mais dont la condition d'arrêt sera celle de la boucle while (en effet aussi étrange que cela puisse paraître, rien n'oblige à ce que la condition d'une boucle for porte sur la variable qu'elle initialise).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    let n2 = n, count; // important: la variable count doit être déclarer ici et pas dans la boucle for
     
    for (count=0; n2 % prime === 0; count++) {
        n2 /= prime;
    }
     
    temp.push(count); // pour qu'elle existe ici (et pas juste dans la boucle for)
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  4. #4
    Inactif  
    Homme Profil pro
    Webmaster
    Inscrit en
    Juin 2021
    Messages
    645
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juin 2021
    Messages : 645
    Points : 1 280
    Points
    1 280
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    (J'ai remplacé compte par count comme ça j'ai l'impression d'être super fort en anglais, tu vas voir, essaie, ça marche!)
    Perso, par chauvinisme sans aucun doute, je préfère écrire tout en Français

    Cela dit... "MAKE FRANCE GREAT AGAIN" sonne mieux que "RENDRE LA FRANCE GRANDE ENCORE " (cf. traduction Gogole)

  5. #5
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Citation Envoyé par jreaux62 Voir le message
    Perso, par chauvinisme sans aucun doute, je préfère écrire tout en Français

    Cela dit... "MAKE FRANCE GREAT AGAIN" sonne mieux que "RENDRE LA FRANCE GRANDE ENCORE " (cf. traduction Gogole)
    Si ça ne tenait qu'à la défense de la langue française (ou par chauvinisme), je serais le premier à garder mes noms de variables et autres en français, mais si on doit reconnaître une qualité à l'anglais, c'est bien sa concision et son coté right to the point, ce qui est bien pratique dans un code dont les instructions sont de toute manière déjà en anglais.
    Mais tant que Superdupont veillera sur notre pays, nous trouverons la force de contrer les projets démoniaques de l'Anti-France et de RENDRE À LA FRANCE SA GRANDEUR D'AUTREFOIS.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Bonjour,
    Citation Envoyé par CosmoKnacki
    (en effet aussi étrange que cela puisse paraître, rien n'oblige à ce que la condition d'une boucle for porte sur la variable qu'elle initialise).
    pas forcément étrange, les données d'initialisation étant optionnelle, elles le sont toutes d'ailleurs :
    Citation Envoyé par ECMAScript
    for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
    et elles peuvent avoir été initialisées en amont ... mais cela reste effectivement une source de soucis.

  7. #7
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Citation Envoyé par NoSmoking Voir le message
    pas forcément étrange, les données d'initialisation étant optionnelle, elles le sont toutes d'ailleurs :
    Oui, je disais "étrange" car généralement on apprend la boucle for avec comme exemple typique l'évolution de la valeur numérique d'une variable dont il est question dans les 3 paramètres (soit for(i=0; i<10; i++)); et on tombe un peu des nues lorsque qu'on se rend compte que les paramètres sont optionnels et assez libres.

    Moi même, je suis passé du BASIC (Thomson) où si je ne m'abuse seules les variations numériques étaient possible: FOR I=0 TO 10 STEP 2:? I; " "; : NEXT I (le STEP facultatif permettant de changer le pas, le ? étant un raccourci pour PRINT), au langage C avec ces paramètres plus libres dont découle le Javascript et PHP. J'imagine donc que mon étonnement de l'époque ne devait pas être si différent.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  8. #8
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2017
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2017
    Messages : 166
    Points : 61
    Points
    61
    Par défaut
    Merci à tous pour votre aide, ça m'a vraiment été utile.
    Désolé pour mon délais de réponse, j'ai fait un break.

    Une dernière question pour la route, dans le poste de jreaux62:
    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
    28
    29
     
    "use strict";
     
    function get_dividedBy( min=2, max=2 )
    {
      let primes = [ 0, 0, 2, 3, 5, 7 ];
      let dividedBy = [];
      let compte = 0;
     
      for( let n=min; n<=max; n++ ) 
      {
        dividedBy.push([0,0]);   // pour chaque n j'ajoute un nouveau sous tableau
        for( let k=2; k<primes.length; k++ ) 
        {  
          let n2 = n;
          while( n2 % primes[k] == 0 ) 
          {
            n2 = Number( n2 / primes[k] );
            compte++;
          }
          dividedBy[dividedBy.length-1].push(compte);
          compte = 0;
        }
      }
      return dividedBy;
    }
    /* ------------ */
    let dividedBy = get_dividedBy( 3, 17 );
    console.log( JSON.stringify(dividedBy) );
    Je suppose que sur cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     n2 = Number( n2 / primes[k] )
    "Number" sert à s'assurer qu'il s'agira bien d'un nombre, mais pourquoi cette précaution à ce moment précis ?

  9. #9
    Inactif  
    Homme Profil pro
    Webmaster
    Inscrit en
    Juin 2021
    Messages
    645
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juin 2021
    Messages : 645
    Points : 1 280
    Points
    1 280
    Par défaut
    Bonjour,

    Citation Envoyé par haddocks Voir le message
    "Number" sert à s'assurer qu'il s'agira bien d'un nombre, mais pourquoi cette précaution à ce moment précis ?
    C'est justement parce que les calculs ne sont pas "précis" en JS (qui n'en est pas à un Number.EPSILON près) !

    6/2 peut donner 3.0000000000000004 comme 2.99999999999999991
    Et comme on a des comparaisons de nombres à faire, ça peut poser problème.

    Number() n'est pas adapté ici (erreur de ma part, cf message suivant)
    Voir math.Round().

  10. #10
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    ce n'est pas le rôle de l'objet Number :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    console.log( .1 + .2);
    // > 0.30000000000000004
    console.log(Number( .1 + .2));
    // > 0.30000000000000004

  11. #11
    Inactif  
    Homme Profil pro
    Webmaster
    Inscrit en
    Juin 2021
    Messages
    645
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webmaster
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juin 2021
    Messages : 645
    Points : 1 280
    Points
    1 280
    Par défaut
    Décidément... (j'ai modifié mon précédent message)




    (ça reste quand même bien pourri cet epsilon qui vient fausser les comparaisons...)

Discussions similaires

  1. Boucle while infinie
    Par marcilles dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 27/12/2018, 09h49
  2. Boucle while infini avec SESSION
    Par ZeeKinio dans le forum Langage
    Réponses: 8
    Dernier message: 29/01/2018, 22h28
  3. Boucle while infinie
    Par BlackoOSX dans le forum Arduino
    Réponses: 5
    Dernier message: 20/06/2016, 21h24
  4. boucle while infini!
    Par guizaniseifislam dans le forum Langage
    Réponses: 2
    Dernier message: 02/03/2012, 01h30
  5. Boucle while infinie
    Par god_enel dans le forum C
    Réponses: 1
    Dernier message: 16/04/2007, 11h35

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