Reduction liste candidat : sudoku

Bonjour,
Au premeir abord mon message parait lnog mais en fait c'est pas long :-p ( en gros je cherche à écrire 3 fonctions en me servant de celle que j'ai écrite )

je devais faire cette fonction :

Écrivez la fonction int reduitCandidatsCase(Grille g, int ligne, int colonne, int val) qui
élimine le candidat de valeur val dans la case de coordonnées (ligne, colonne). Cette fonction
retourne le nombre de candidats éliminés (i.e. 0 ou 1).

j'ai écris cette fonction :

int reduitCandidatsCase ( Grille g, int lig, int col, int n) {
int i; /* position de n dans le tableau des candidats */
int ne; /* nombre de candidats éliminés */
lig = lig - 1;
col = col - 1;
ne = 0;
i = rechercheTabInt(g[lig][col].candidats, g[lig][col].nbCandidats, n);
if ( i != -1) {
g[lig][col].nbCandidats = g[lig][col].nbCandidats - 1;
while (i < g[lig][col].nbCandidats) {
g[lig][col].candidats[i] = g[lig][col].candidats[i+1];
i = i + 1;
}
ne = 1;
}
return ne;
}

elle marche bien mais maintenant j'aimerais écrire 3 autres fonctions qui ressemble à celle là :

Il faut écrire la fonction int reduitCandidatsLigne(Grille g, int ligne, int val) qui parcourt les cases
vides de la ligne d'indice ligne et qui y élimine les candidats de valeur val. Cette fonction
retourne le nombre de candidats éliminés sur toute la ligne.

Il faut écrire la fonction int reduitCandidatsColonne(Grille g, int colonne, int val) qui parcourt les
cases vides de la colonne d'indice colonne et qui y élimine les candidats de valeur val. Cette
fonction retourne le nombre de candidats éliminés sur toute la colonne.

Iil faut écrire la fonction int reduitCandidatsRégion(Grille g, int region, int val) qui parcourt les
cases vides de la région d'indice region et qui y élimine les candidats de valeur val. Cette
fonction retourne le nombre de candidats éliminés sur toute la région.

Si quelqun a une idée je le remercie d'avance :)
bioux a tous
Configuration: Windows XP
Firefox 2.0.0.14

33 réponses

Résumé de la discussion

L'écriture de trois fonctions en C pour éliminer des candidats dans une grille Sudoku (ligne, colonne et région) et retourner le nombre de candidats éliminés est au cœur des échanges. Plusieurs intervenants proposent de réutiliser reduitCandidatsCase pour écrire reduitCandidatsLigne, reduitCandidatsColonne et reduitCandidatsRegion, avec des boucles sur les éléments de chaque ligne/colonne/région et une mise à jour progressive des candidats. Des débats portent sur l'architecture mémoire et les compromis entre stocker 9 candidats par case ou 27 entiers pour toute la grille, ainsi que sur la délégation des calculs aux passes successives. Réponses évoquent aussi une mise en œuvre itérative jusqu'à nbModif zéro et soulignent que la fonction accrue ne peut ignorer les interactions avec les colonnes et régions.

Bobot (l’IA à votre service)
  1. Oui, les fonctions de départ. J'avais pensé que ça avait été fait avant de passer à la suite ^^"

    En gros:

    Pour chaque ligne
    on réduit les candidat (de chaque valeur ? Je sais plus si elle est en paramètre)

    pour chaque colonne
    on réduit les candidats de la colonne

    pour chaque région
    ..

    int ligne;
    int val;
    
    for ( ligne = 0 ; i != 9 ; i++ )
        for ( val = 1 ; val != 10 ; val++ )
            réduitCandidatsLigne( g, ligne, val );
    
    


    Je me demande si il y a une futilité. Genre est-ce qu'il faut refaire les lignes après avoir fait certaines colonnes ou régions et idem avec les autres. J'en sais vraiment rien, on verra bien si ça marche avec ça.

    Pour la validation il faut reprendre les trois fonctions précédentes et les appliquer tant qu'on peut (enfin je crois je relis pas je suis un peu pressé...)

    Entier nbModif = 1; // on amorce
    
    Tant que nbModif != 0
    {
        int i;
    
        nbModifs = 0;
    
        nbModif += candidats_cache_ligne( g );
        nbModif += candidats_cache_colonne( g );
        nbModif += candidats_cache_region( g );
    }
    


    A bientôt j'espère ;-)
    M.

    Diantre, rencard raté et cette réponse qui s'échappe ! :-D
    0
    1. Je n'ai pas vu où était demandée la première fonction, c'est dans quel point ? (je ne râle pas j'essaie juste de suivre ^^")

      Voyons voyons mademoiselle Marie... on se fait des sudokus de 81 par 81 ? ^^
      Accessoirement on peut en faire des for plutôt que des while.

      Pour l'erreur de compilation c'est parce que...
      Madame a très certainement demandé des int avec 0 ou 1 comme valeur de retour car le type bool n'existe pas en C. C'est du C++, true et false aussi. Par contre je ne suis pas convaincu que ce soit exactement là dessus que le compilateur râle. Ce qui serait gênant d'ailleurs. il y a peut-être moyen de le forcer à compiler avec les normes C et non C++. Il faut regarder dans les options du projet.

      En passant et c'est auxiliaire : Il est conseillé de faire :
      int i = 1;

      plutôt que :
      int i;
      i = 1;
      


      Et puis quand même ! Je suis content de voir un code où les variables utilisées sont déclarées, où il y a les ; les accolades fermantes et la totale. Fallait que je te le dise. ^^

      2.3.4
      2. Programmez la fonction void candidats_caches_ligne(Sudoku s) qui trouve et note les candidats
      cachés sur des lignes. Pour cela, on définira une fonction int compte_occurences_ligne(Sudoku
      s, int ligne, int val, int *colonne) qui renvoie le nombre de fois ou val est candidat sur la
      ligne ligne et positionne dans colonne le numéro de la première colonne dans laquelle se trouve
      une occurence de val.

      Je ne sais plus qu'est-ce qu'il faut faire. C'est int candidatsCachesLigne(Grille g) ou void candidats_caches_ligne(Sudoku s) ?

      void candidats_caches_ligne( Sudoku s )
      {
          int ligne
          int val
      
          for ( i=0 , i<8 , i=0 ) 
          {
      
              for ( val =1 ; val < 9 ; val ++ ) 
              {
                  int colonne
                  int nbCandidats 
      
                  ...
      
              }
          }
      }
      

      Je suis d'accord à part les conditions qui s'arrêtent un tour trop tôt et le "," à la place des ";" dans le premier for

      >> mais c'est mort car de toute facon c'est trop compliqué et puis
      Je dirais plutôt : pourquoi tu t'es arrêtée en si bon chemin ? Même si c'est pas exactement ça même un truc à moitié faux ça reste à moitié bon donc on avance toujours. Propose ce à quoi tu penses, promis je mords pas. Du moins, pas trop fort. ^^"

      Je te laisse corriger et proposer la suite ou poser des questions :)

      et pour 032 je te le dirais ce soir :p Un rencard ?

      M.
      0
      1. en fait pour revenir a la question de départ, tu t e souviens des 3 fonction reduirecandidatligne , reduirecandidat colonne , reduire cnadidat region ?

        en utilisant ces trois fonctions , il faut que j'écrive la fonction void reduireCandidats(Grille g)
        qui réduit les listes de candidats de toutes les cases de la grille.
        je vois pas comment faire , j'avais pensé a ajouter les 3 fonctions mais ca me parait bizarre

        Règle 1 Si une case de la grille possède une liste de candidats réduite à une valeur unique
        alors cette valeur doit être notée dans la case.

        4. Ecrire une fonction int valideCandidatsUniques(Grille g) parcourant l’ensemble des cases de
        la grille et essayant d’y appliquer la règle ci-dessus. Cette fonction renvoie ensuite le nombre de
        valeurs non nulles qui ont été ajoutées dans la grille. A chaque modification de l’état de la grille,
        la liste des candidats doit être à nouveau réduite afin de conserver une grille respectant les règles
        du jeu du Sudoku. Pour cela, écrire une fonction void marqueCase(Grille g, int ligne, int
        colonne, int val) qui marque la valeur val dans la case de coordonnées (ligne, colonne) et met à
        jour les listes de candidats des cases de la ligne, colonne et région de la case marquée.

        5. Ecrire une fonction int resoudGrille(Grille g) qui applique autant que possible la fonction int

        valideCandidatsUniques(Grille g) et qui renvoie le nombre de modifications qui ont été faites
        dans la grille

        int valideCandidatUnique ( grille g ) {

        int i ;

        for ( i=0 ; i< 9 ; i++ ) {

        for ( j=0 ; j<9 ; j ++ ){

        je pense qu'il faut écrire if g[i][j] = reduirecandidat = 1 alors g[i][j] = ce canddiat , non ?

        void marquecase ( grille g, int ligne, int colonne, int val ) {

        g[ligne][colonne] = val

        par contre je ne sais pas comment mettre a jour les candidats

        c'est la dernière fois que je t'embete , ce soir j'arrête le sudoku ^^
        0
        1. POUR LE CODE :

          bool estresolue ( Grille g ) {

          int i ;
          int j ;

          i=1 ;
          j=1;

          bool repe ;

          repe = false ;

          if (estValide(g)) {

          while (i<81) {

          while (j< 81) {

          if ( g[i][j].val>= 1 && g[i][j].val <= 9 )

          {
          i++;
          j++;
          repe = true ;
          }

          else

          return (repe);
          }
          }

          }
          return (repe);
          }

          ca m'affiche :

          parse error before `repe'
          `repe' undeclared (first use in this function)
          (Each undeclared identifier is reported only once
          for each function it appears in.)

          si tu sais pour quoi ??

          POUR CACHER CANDIDIATS :

          void candidats_caches_ligne( Sudoku s )
          {
          int ligne
          int val

          for ( i=0 , i<8 , i=0 ) {

          for ( val =1 ; val < 9 ; val ++ ) {

          int colonne
          int nbCandidats

          mais c'est mort car de toute facon c'est trop compliqué et puis tu dis :

          "3. Ecrire la fonction int candidatsCachesLigne(Grille g) qui trouve et note les candidats cachés sur les lignes puis retourne le nombre de candidat cachés notés.
          Il n'est pas demandé que la fonction retourne quoi que ce soit, d'ailleurs son type de retour est void. "

          or juste au dessus il y a écrit retourne le nombre de candidats cachés noté ^^

          et pour 032 je te le dirais ce soir :p
          0
          1. Le 2.3.4, point numéro 2, définit deux fonctions :

            void candidats_caches_ligne( Sudoku s ); (OK)
            int compte_occurrences_ligne( Sudoku s, int ligne, int val, int * colonne ); (Pas top)

            Et puis tu diras pour moi à madame qu'à occurrences y a deux r.

            >> 3. Ecrire la fonction int candidatsCachesLigne(Grille g) qui trouve et note les candidats cachés sur les lignes puis retourne le nombre de candidat cachés notés.
            Il n'est pas demandé que la fonction retourne quoi que ce soit, d'ailleurs son type de retour est void.

            Pseudo-codons mais je ne fais que celle-ci. (en mettant les jolies balises pour garder la mise en forme du code)

            void candidats_caches_ligne( Sudoku s )
            {
                Entier ligne
                Entier val
            
                Pour chaque : ligne ligne du sodoku s
                    A partir de ligne = 0
                    Jusqu'à ligne = 8
                    De 1 en 1
                faire :
                {
                    Pour chaque : valeur val de la ligne ligne du sudoku s
                        A partir de val = 1
                        Jusqu'à val = 9
                        de 1 en 1
                    faire :
                    {
                        Entier colonne
                        Entier nbCandidats <- compte_occurrences_ligne( s, ligne, val, OUT colonne )
            
                        Si nbCandidats = 1 // Ce candidat ne peut aller que 
                                           // dans une seule case de la ligne
                        {
                            // Je ne sais pas comment on joue une valeur dans une case...
                            // Il doit y avoir des fonctions qui en même temps mettent à jour les
                            // tableaux des candidats et tout le tatouin...
            
                        } //fin Si
            
                    } // Fin boucle valeur
                } // Fin boucle ligne
            
            }
            


            Je te laisse compléter la fonction compte_occurrences_ligne
            Bien évidemment si ça compilait ça serait encore plus beau :o)

            Y a un autre truc que j'ai trop compris non plus, le "032"... ^^

            M.
            0
            1. t'aime bien les pseudo avec les syllabes qui se ressemblent ^^

              Ecrire la fonction int chercheCandidatCacheLigne(Grille g, int ligne, int val) qui pour la ligne ligne
              retourne le numéro de la colonne où se trouve le candidat caché val, ou -1 si il n'y en a pas.

              3. Ecrire la fonction int candidatsCachesLigne(Grille g) qui trouve et note les candidats cachés sur les lignes
              puis retourne le nombre de candidat cachés notés.

              je me demande s'il ne faut pas utilisé la première fonction ??

              le truc c'est qu'il faut noté le candidat caché de la ligne et à chaque fois qu'on en note 1 , on ajoute +1

              est ce q'uil faut faire :

              for ( i < 9 pour arcourir les 9 lignes et en meme temps faire un for ( j< 9 pour parcourir les 9 cases de la ligne

              tu peux pas me montrer un pseudo code toi aussi ? :ange:
              0
              1. C'est toujours le même, je laisse tomber mon nom de scène, de toute façon j'étais pas drôle m'a-t-ton déclaré.
                Ma carrière de comique de forum est ruinée ! :'(

                Heureusement que Julie est partie... Marie est bien plus sympa ^^"

                Moi ce que je trouve dommage c'est mademoiselle Souriceau avait donné l'entête des fonctions à faire et que ... bah...

                Sinon je suis un petit peu d'accord avec toi... ça craint un peu. Surtout la fonction appelée avec avec les types encore dans l'appel de fonction, un paramètre ligne venu de nul part...

                D'où la question suivante, veux-tu de l'aide pour Dev-Cpp, ton nouveau compilateur chéri et adoré ?

                Par contre il faut bien avouer que la fonction du compteur est impeccable, il reste a mettre le paramètre qui manque et on peut l'encadrer pour la mettre au mur. (comme quoi, ça m'arrive d'être content des fois...)

                Je crois que la fonction candidats_caches_ligne doit faire toutes les lignes, et pour chaque ligne elle traite chaque valeur et à chaque valeur, si... alors on notera la valeur. C'est ce que j'ai compris du pdf.

                M.
                0
                1. bonsoir zigzag

                  je vias essayé :

                  int compter_occurrences-ligne (int val, int ligne)
                  {
                  int compteur = 0 ;

                  for(j=0; i < 9 ; j++)

                  if( g[ligne][j] == val)
                  compteur++;

                  return compteur;
                  }

                  void candidatcachéligne ( grille g ) {

                  int i;

                  for ( i=0 ; i<9 , i++ ) {

                  compter-occurences-ligne ( int vla , int ligne

                  ca craint un peu mon code en fait ^^
                  0
                  1. Si possible un code qui utilise compte_occurences_ligne
                    Plouf ! Plus de compteur dans cette fonction ci ;-)
                    0
                    1. Re-bonjour ! ^^

                      J'ai compriiiiis ! Il aura fallu le temps mais bon... Au moins moi je n'ai pas de trouble de la personnalité <|:o)

                      Je cherchais trop compliqué, la fonction pour les lignes ne prends pas en compte les colonnes ou les régions pour trouver ses choix. (En fait c'est déjà fait par la mise à jour des candidats)

                      Tu proposes un pseudo code ?
                      0
                      1. en fait les fonctions proviennent d'ici :

                        http://vero.moriceau.free.fr/cours/sudoku.pdf

                        mais j'ai pas trop compris pour les candidats cachés
                        ca ferait
                        void candidatcachéligne ( grille g ) {

                        int i

                        for ( i=0 ; i<9 , i++ ) {

                        et la c'est le vide ( j'ai pas trop le compteur )
                        0
                        1. Oups, je voulais éditer pour que tu n'oublies pas le message 21 sur la page précédente et un message est retombé :-/

                          Oups !
                          Désolé.
                          0
                          1. Pour l'instant, la seule chose qui te largue en info c'est ton manque de confiance en toi. T'as l'algo, le code sors comme il faut aussi... y manque toujours un ; de-ci de-là mais je pense que grand-mère dans ton rocking-chair t'en oublieras encore, comme tout le monde... Le seul truc qui peut te manquer c'est de la pratique mais t'as le droit de pas aimer l'info et de ne plus vouloir en faire après la fac, personne t'en voudra

                            (Sauf moi ! Gnark gnark gnark !)
                            J'en ai marre d'être "gentil" :'(

                            Pour Dev-Cpp, la première chose est de créer un projet avec l'assistant, puis de rajouter tes fichiers. Eventuellement de virer le leur si tu as ton main. Dev-cpp utilise Gcc aussi comme compilateur.
                            0
                            1. Je t'appellerai Julie. C'est le pseudo que tu t'es choisi, un point c'est tout. C'est une raison bien suffisante.
                              On doit te dire souvent que tu es trop gentille...

                              je suis pas aussi bête que tu peux le penser
                              Ah là, pour une fois... Tu me déçois. :'(

                              A demain peut-être (si tu es là)
                              ;-)
                              0
                              1. Pour l'instant, la seule chose qui te largue en info c'est ton manque de confiance en toi. T'as l'algo, le code sors comme il faut aussi... y manque toujours un ; de-ci de-là mais je pense que grand-mère dans ton rocking-chair t'en oublieras encore, comme tout le monde... Le seul truc qui peut te manquer c'est de la pratique mais t'as le droit de pas aimer l'info et de ne plus vouloir en faire après la fac, personne t'en voudra

                                (Sauf moi ! Gnark gnark gnark !)
                                J'en ai marre d'être "gentil" :'(

                                Pour Dev-Cpp, la première chose est de créer un projet avec l'assistant, puis de rajouter tes fichiers. Eventuellement de virer le leur si tu as ton main. Dev-cpp utilise Gcc aussi comme compilateur.
                                0
                                1. Je me doute que tu t'apelles pas zigzag ^^

                                  tu peux m'appeler marie je comprendrais :D ( je suis pas aussi bête que tu peux le penser , au vue de tout ce que je demande )

                                  bon j'y vais , bonne nuit et merci encore ++
                                  0
                                  1. j'ai paniqué pour rien je crois car la fonction reduirecase élimine la valeur

                                    ouf j'ai eu une petite frayeur ( c'est parce que je dois tout rendre demain ... oui je sais je m'y prend au dernier moment )
                                    0
                                    1. par contre je me demande si on s'est pas trompé dans les fonctions car dnas la consigne yavé écrit :

                                      écrire la fonction int reduitCandidatsLigne(Grille g, int ligne, int val) qui parcourt les cases
                                      vides de la ligne d'indice ligne et qui y élimine les candidats de valeur val. Cette fonction
                                      retourne le nombre de candidats éliminés sur toute la ligne.

                                      et dans nos fonction on élimine rien , non ? ( parce qu'avant il demandait d'écrire la focntion supprimer la valeur d'un tableau )
                                      0
                                      1. Oki, c'est donc ça qu'on ne reconnaît pas la patte de l'auteur par rapport au premier post. ^^"

                                        Ca te dérange si je continue à t'appeler Marie ?
                                        Je vais t'avouer un truc mais faut que ça reste entre nous ok ? Mon vrai nom c'est pas Zigzag ! :D (désolé, Julie)

                                        Pardon, je vais redevenir plus... enfin moins c** surtout ^^".
                                        0
                                        1. comme ca ? :)

                                          int reduitCandidatsRégion(Grille g, int region, int val)
                                          {
                                          int i;
                                          int j;
                                          int pos_ligne = (region / 3) * 3;
                                          const int pos_colonne = (region % 3) * 3;
                                          const int nbCandidatsElimines = 0;

                                          for( i = pos_ligne ; i < pos_ligne + 3 ; i++ )
                                          {
                                          for( j = pos_colonne ; j < pos_colonne + 3 ; j++ )
                                          {
                                          nbdecandidat = nbdecandidat + reduitCandidatsCase( g, j ,i , val );
                                          }
                                          }

                                          return nbCandidatsElimines;
                                          }

                                          Je suis en train de télécharger dev - c++ pour le compilateur ^^

                                          Comme ca se fait que tu sois aussi fort ?? ( même si c'est vrai que moi je fais ça uniquement car on me le demande , à chaque fois je suis larguée en info :p )

                                          et je t'admires beaucoup car t'aides et en plus t'es gentil ( et t'essayes de faire de l'humour, lol ) contrairement a mon professeur d'informatique ...
                                          0
                                          • 1
                                          • 2