Annonce

Réduire
Aucune annonce.

Faire de l'aléatoire sans revenir sur un élément (Algorithme)

Réduire
X
 
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • Faire de l'aléatoire sans revenir sur un élément (Algorithme)

    Salut chers Hackademiciens,
    J'étais entrain de travailler sur un petit projet web, qui consistait à faire un QCM Informatique (Programmation, Hacking, Réseaux, Informatique Générale, ...) en JavaScript.
    Alors lors de la génération de questions, j'ai voulu que les questions s'affichent d'une façon aléatoire et pour cela j'ai utilisé la classe "Math" de JavaScript et sa méthode "Random" et tout a bien fonctionné, mais je me suis rendu compte que cette façon de le faire pouvait revenir sur une question plusieurs fois et ce qui est embettant pour la personne qui joue (Imagine qu'on te pose une question plusieurs fois dans une partie de jeux ) du coup j'ai commencé a reflechir pour pouvoir trouver un moyen pour éviter cette répétition là mais en gardant l'aléatoire.

    Et donc en refléchissant j'ai écrit un algorithme qui m'aide à faire cela
    Voici le principe :
    - Je crée un tableau contenant les éléments a trier (Ces élèments constituent en elles même les questions du QCM)
    - Puis je commence à trier ce tableau d'une façon aléatoire
    - Puis je crée un autre tableau qui va commencer à prendre l'élèment (i) traité et le stocker
    - Et puis à la fin c'est ce tableau que j'affiche!

    Du coup mes questions sont en aléatoire et on ne revient pas sur une question!

    Voici le code de cet algorithme que j'ai implémenté en JavaScript (fichier code.js) :

    Code:
    function randomWithoutRep() {
    
    	//Le tableau contenant les éléments à trier
    	var tab = [18, 24, 3, 14, 53, 26];
    	var i = 0;
    	var taille = tab.length;
    
    	//Le tableau qui va commencer a stocker les éléments trier
    	var tab1 = [];
    	
    	while(i < taille) {
    		var index = taille-i-1;
    		var aleatoire = parseInt(Math.random() * index);
    		var temp = tab[aleatoire];
    		tab[aleatoire] = tab[index];
    		tab[index] = temp;
    		var element = tab.pop();
    
    		tab1.push(element);
    		alert(tab1);
    		i++;
    	}
    }
    randomWithoutRep();
    Pour tester ceci, créer juste un fichier index.html auquel vous incluez le fichier code.js

    PS : C'est juste un algorithme, donc vous pouvez le modifier comme vous voulez et le tester avec les questions à l'interieur du tableau et enlever le alert().
    Je suis ouvert aux critiques
    <?php
    $signature = NULL;
    ?>

  • #2
    Merci bien pour ce code et les explications.

    Commentaire


    • #3
      Je ne suis certainement pas très réveillé mais je ne comprends pas en quoi ton algorithme empêche qu'une question soit présentée plusieurs fois.
      Je vois que en gros tu fais un shuffle sur un tableau mais si tab contient plusieurs fois le même nombre, il sera également présent plusieurs fois dans ton tableau trié.

      Petite question concernant l'algorithme en lui même toutefois : Pourquoi crées tu un second tableau ? Es tu certain de son utilité ? Pourquoi ne pas simplement inverser l'ordre des éléments dans ton premier tableau ?
      Créer deux tableaux c'est allouer deux fois plus de mémoire. Alors je connais le débat de nos jours avec la puissance des ordis ça ne change pas grand chose mais je dirais que c'est avant tout une bonne pratique de programmation que de prendre le moins de ressource possible.

      Commentaire


      • #4
        Anonyme77,
        Merci pour ton remarque sur l'utilisation de tableau.
        Je vais tenter de me justifier :
        D'abord sache que les éléments qui sont dans le premier tableau ne sont qu'un exemple! En vrai c'est sont de questions et ces questions pour etre affichées, elles doivent être parcourues par une boucle mais comme le principe est que le QCM doit affiché seulement une question puis aller sur "suivant" par exemple et pas l'ensemble de questions du tableau alors pour cela je les trie aléatoirement mais lors du tri, pour éviter que lors de l'affichage qu'on reviennent sur un element encore une fois, alors je crée un autre tableau qui copie et stock les elements (ou les questions) du premier tableau mais cette fois ce tableau contient les questions trié aléatoirement et du coup je fait une boucle qui se charge juste d'afficher les éléments déjà trié!
        L'aléatoire je le fait seulement lors du parcours du premier tableau, mais le second lui contient les elements deja trié et je les affichent simplement.

        J'espère que tu m'as compris mais je sais que je ne suis pas bon en matière d'explication ça m'arrive si souvent d'avoir de difficultés à me faire comprendre...
        Dernière modification par Mahi2, 05 août 2015, 14h21.
        <?php
        $signature = NULL;
        ?>

        Commentaire


        • #5
          Bonjour,
          pourquoi ne pas déclarer une structure qui vous permet d'avoir d'une partie la question, et d'une autre partie un indicateur qui après chaque passage si cette question est déjà sélectionnée, l'indicateur prend une valeur constante que vous aurez fixé de tel en sorte que si le programme revient sur cette question, cet indicateur ne le permettra pas d'y accéder. Ainsi de rejoins anonyme77 dans ses propos et je pense qu'il y'a gaspillage de la mémoire car vous avez déclarer des tableaux (02) statique que vous parcourez. si nous regardons la complexité elle n'est pas optimal.

          Commentaire


          • #6
            Bonjour

            Je suis d'accord avec les autres réponses à propos des 2 tableaux.
            Si tu fait un code pour t'en servir toi même sur ton pc c'est pas catastrophique pour des petites quantités de mémoire mais ce n'est pas propre.
            Si tu code en javascript je suppose que ton code à pour but d'aller sur internet (ou au moins un serveur perso avec tes amis qui peuvent s'y connecter). dans ce cas la tu auras au minimum un code plus lent à réagir si beaucoup de gens jouent en même temps (à confirmer par quelqu'un ayant plus d'expérience que moi sur la programmation d'applis réseau^^)

            une autre solution serait de mélanger aléatoirement ton tableau :
            tu choisis 2 entiers qui servent d'indices de ton tableau et tu échange les éléments à ces emplacements
            En faisant ca plusieurs fois tu mélangera donc ton tableau sans risques de doublons puisque tu ne créé pas de nouvel élément

            Ensuite tu utilise les X premiers éléments de ton tableau qui correspondent à tes questions choisies aléatoirement.
            ca ne devrait pas poser de problèmes pour afficher seulement 1 question à la fois puisqu'il suffit de faire une boucle de 0 à X en passant à la suite uniquement une fois que tu as obtenu une réponse

            A voir si la solution de succès est plus efficace que celle ci en terme d'optimisation mais comme je t'ai dit je ne suis pas expert en appli réseau ni en javascript

            Commentaire


            • #7
              succès, oui c'est une bonne proposition, j'en tiendrai compte pour le rendre optimal

              oliver39, C'est un petit projet que j'ai moi même décidé de créer en vue de m'améliorer, je m'amuse souvent à concevoir des petits algorithmes comme ca.
              Mais oui, je suis d'accord avec tes critiques, j'en tiendrai compte et surtout merci beaucoup
              <?php
              $signature = NULL;
              ?>

              Commentaire


              • #8
                Je connais pas javascript, mais je suis pratiquement certains que les mêmes méthodes de listes doivent exister et être équivalentes à python...

                Code:
                >>> questions = []
                >>> for i in range(10):
                ...     questions.append('question n°{}'.format(i+1))
                ... 
                >>> questions
                ['question n°1', 'question n°2', 'question n°3', 'question n°4', 'question n°5', 'question n°6', 'question n°7', 'question n°8', 'question n°9', 'question n°10']
                >>> from random import shuffle
                >>> shuffle(questions)
                >>> questions
                ['question n°10', 'question n°2', 'question n°4', 'question n°3', 'question n°1', 'question n°7', 'question n°9', 'question n°5', 'question n°8', 'question n°6']
                >>> while questions:
                ...     print(questions.pop())
                ... 
                question n°6
                question n°8
                question n°5
                question n°9
                question n°7
                question n°1
                question n°3
                question n°4
                question n°2
                question n°10
                En gros une méthode shuffle permettant de mélanger les éléments de la liste et une méthode pop retirant le dernier élément de la liste et l'affichant jusqu'à que la liste soit vide (à l'aide d'une boucle).

                Rien de compliqué, et très simple à implémenter dans les langages objets en règle générale.

                Commentaire


                • #9
                  Merci @fred,
                  J'ai cherché comment implementé une liste en JavaScript et comme ça j'allais commencé à faire le pop() sur chaque element de cette liste et l'affiché mais je n'ai pas trouvé malheureusement, du coup j'ai fait avec ce que je connaissais.
                  <?php
                  $signature = NULL;
                  ?>

                  Commentaire


                  • #10
                    Pour shuffle, tu implémentes une méthode supplémentaire shuffle

                    Code:
                    Array.prototype.shuffle = function() {
                        var input = this;
                         
                        for (var i = input.length-1; i >=0; i--) {
                         
                            var randomIndex = Math.floor(Math.random()*(i+1)); 
                            var itemAtIndex = input[randomIndex]; 
                             
                            input[randomIndex] = input[i]; 
                            input[i] = itemAtIndex;
                        }
                        return input;
                    }
                    Source

                    Le principe me semble-t-il (je peux me tromper) est d'hériter de la classe Array et d'y ajouter la méthode shuffle...

                    Une fois le mélange fait, utiliser pop jusqu'à avoir une liste vide et non utilisable !

                    Maintenant tout ça réuni fait un code propre ! Ne me force pas à faire du javascript

                    Commentaire


                    • #11
                      Ne me force pas à faire du javascript
                      Non fred, loin de là! Pourquoi? tu n'aime pas JavaScript?
                      <?php
                      $signature = NULL;
                      ?>

                      Commentaire


                      • #12
                        tu n'aime pas JavaScript?
                        Si je devais en faire, je le ferais, mais si je peux éviter pour un équivalent que je connais déjà, alors j'évite...

                        Je ne regarde pas trop si j'aime ou si j'aime pas, c'est plus une question de besoin, et pour l'instant je n'en ai pas besoin, donc je préfère m'investir sur ce sujet en restant dans la conception, plus que dans la syntaxe.

                        Commentaire


                        • #13
                          Oui, je vois et comprend @fred, sinon je te remercie pour éclaircissement sur mon post
                          <?php
                          $signature = NULL;
                          ?>

                          Commentaire


                          • #14
                            le topic a l'air vieux, mais en le lisant une quesiton me vient en tête pour @Fred
                            "Si je devais en faire, je le ferais, mais si je peux éviter pour un équivalent que je connais déjà, alors j'évite." ??? c'est quoi comme équivalent à Javascript que tu utilse et connais déjà?

                            Commentaire


                            • #15
                              Envoyé par dramslinux Voir le message
                              c'est quoi comme équivalent à Javascript que tu utilse et connais déjà?
                              Pour ton information dramslinux, Fred est super modérateur et donnes des cours de python, il nous aides beaucoup ici avec ces cours.
                              <?php
                              $signature = NULL;
                              ?>

                              Commentaire

                              Chargement...
                              X