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

 C Discussion :

Sudoku avec fichier


Sujet :

C

  1. #61
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Pour ChangeCase(), il y a une erreur dont je suis responsable, l'ayant faite en transcrivant l'algo du message #57 (je corrige ce message). Comme quoi, il te faut faire une lecture critique et ne pas te fier aveuglément.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       if (grille[ligne][col][0]==0 && val!=0)
    Pour entre_valeur(), elle devrait recevoir grille en argument et non pas utiliser une variable locale : on a besoin de cette grille en dehors de cette fonction.
    On peut regrouper l'entrée des valeurs soit sur fichier, soit sur clavier en passant aussi un FILE* et en faisant un fscanf(). Si on veut l'entrée au clavier, on appellera la fonction avec stdin en argument.
    Donc :
    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
    void entre_valeur(FILE * f, Grille grille)
    { int ligne=0, col=0;  //Lecture des valeur entre par l'utilisateur
      int k;
      int val;
      if(f==stdin)
      {
        printf("\n");
        printf("Entrer ligne par ligne les %d chiffre de votre grille.\nMettez des 0 pour les cases vide \n\n",MAX);
      }
      for (ligne=0; ligne<MAX; ligne++)
        for (col = 0; col < DIM; col++)
           for(k=0; k<DIM+1;k++) grille[ligne][col][k] = k!=0;
      for (ligne = 0; ligne < DIM; ligne++)
        for (col = 0; col < DIM; col++)
        { 
              fscanf(f,"%1d", &val);
              ChangeCase(grille,ligne,col,val);
        }
    }
    int main(void)
    {
      Grille grille;   
      entre_valeur(stdin,grille);
      system("pause");
      return 0;
    }
    Qu'est-ce que ces MAX et ces DIM qui se mélangent ? Pourquoi sont-ils utilisés dans une des fonctions et pas dans l'autre ? Il faut être homogène dans son codage.

  2. #62
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 45
    Par défaut
    Bonjour,

    Donc se matin, j'ai taper reste de la regle 1 :

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    int TestCase(Grille grille, int ligne,int col)
    { int i,k;
      int p;
      i=0;
    for (ligne = 0; ligne < MAX; ligne ++)
      { for (col <= 0; col <= MAX; col ++)
        { if ( grille[ligne][col][0] == 0 )
            for (k = 1; k <= 10; k++)
              { if ( grille[ligne][col][k] == 1)
                     i=i+1;
                     p=k;
              }
            else if (i = 1)
                   ChangeCase(grille,ligne,col,k);
            else  
                 if (i = 0) return 0;
                        else return -1;
        }
      }
    }
     
     
     
    int TestGrille(Grille grille)
    { int ligne,col;
       for (ligne = 0; ligne < MAX; ligne ++)
        for (col <= 0; col <= MAX; col ++)
           TestCase(grille,ligne,col);
    }
     
    void regle1(Grille grille)
     { while ( TestGrille(grille) == 1 )
       TestGrille(grille);
    }
     
     
    /*******************MAIN*******************************/
    int main(void)
    {   Grille grille;   
      entre_valeur(stdin,grille);
      afficher_grille(grille);
      //verification_colonne(grille);
      //verification_ligne(grille);
      //verification_carre(grille);
      regle1(grille);
     
      system("pause");
      return 0;
    }
    Mais règle 1 ne serait pas plutôt une procedure ? car elle ne retourne rien.

    Apparemment j'ai un petit probleme dans la fonction TestCase, je vais essaye de le régler.
    Je viens de voir que j'ai aussi un rapport de 10 pages a faire sur le sujet...

  3. #63
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    * Soigne l'indentation du code, c'est pénible à lire

    * TestCase()
    Tu n'es pas assez attentif :
    - Ta fonction teste la grille, pas UNE case de la grille. Dans ce cas, ligne et col ne seraient pas des paramètres mais des variables locales.
    - Qu'est-ce ce for : for (col <= 0; col <= MAX; col ++) ???
    - et pour celui-ci : for (k = 1; k <= 10; k++) k doit s'arrêter à 9, pas à 10
    - la comparaison se fait avec == pas avec =.
    - i compte le nombre de 1 pour une case, il faudrait le remettre à 0 avant de commencer la case suivante.
    - La fonction doit retourner 1 si au moins une case a été changée, il faut un indicateur supplémentaire si on traite toute la grille.
    - Des erreurs de placement des {} qui délimitent les blocs de façon erronée.
    - ...

    En gardant l'allure générale de ta fonction, le code devient pour une case (non compilé, non testé)
    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
    int TestCase(Grille grille, int ligne, int col)
    { 
      int i,k,p;
      if (grille[ligne][col][0] == 0)
      {    
         for(i=0, k=1; k<MAX+1; k++)
            if ( grille[ligne][col][k] == 1)
            {
               i++;
               p = k;
            }
         if (i == 1)
         {
            ChangeCase(grille,ligne,col,p);
            return 1;
         }
         if (i == 0) return -1;     
      }
      return 0;
    }
    * TestGrille()
    - encore une aberration : for (col <= 0; col <= MAX; col ++)
    code : (non compilé, non testé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int TestGrille(Grille grille)
    { 
      int ligne,col;
      int res;
      int mod = 0;
      for (ligne = 0; ligne < MAX; ligne ++)
        for (col = 0; col < MAX; col ++)
        {
           res = TestCase(grille,ligne,col);
           if(res == -1) return -1;
           mod = mod || res == 1;
        }
      return mod;     
    }
    * regle1()
    Lorsqu'on utilisera plusieurs règles, il faut savoir si au moins l'une d'elles a été utilisée auquel cas la résolution n'est pas terminée (par un succès ou un échec). C'est pourquoi, ces fonctions tranmettent un indicateur.
    code : (non compilé, non testé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int regle1(Grille grille)
    { 
      int mod = 0;
      do
      {   
        res = TestGrille(grille);
        if(res == -1) return -1;
        mod = mod || res == 1;
      } while ( res == 1 );
      return mod;
    }
    As-tu réfléchi à la règle suivante ? (celle-ci est notoirement insuffisante)

  4. #64
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 45
    Par défaut
    En effet, j'ai fais des erreur d'inatention, car mes examens commence lundi, donc entre le sudoku et mes revision je suis un peu perdu.

    Donc j'ai changer les fonction par toutes les nouvelle.

    J'ai effectué un test pour voir si il n'y a pas de probleme.

    Apparemment il me mes bien la valeur voulu en premier ligne, mes un 0 apparait a la premier case de la deuxième ligne, et le reste il me le fais plus.

    Voici une capture du résultat
    Images attachées Images attachées  

  5. #65
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    mes un 0 apparait a la premier case de la deuxième ligne
    Il y a donc une erreur quelque part puisqu'il ne doit pas être posssible de mettre une case à 0.
    Normalement, tout changement de valeur d'une case passe par la fonction ChangeCase(), ce qui amène à la suspecter.

    As-tu corrigé l'erreur de test dans la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void ChangeCase(Grille grille,int ligne, int col, unsigned char val)
     { int i,j,k;
         
       if (grille[ligne][col][0]==0 && val!=0) ....

  6. #66
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 45
    Par défaut
    Oui, j'ai bien changer cette erreur. J'essaye de trouver l'erreur dans ChangeCase()

    EDIT :Je n'arrive pas a trouver l'erreur pourtant, le programme fonctionne que sur la ligne 1, si je mes un 0 a une autre ligne il ne fait rien.

  7. #67
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Il y a des erreurs ici : (dépassement du tableau)
    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
    void ChangeCase(Grille grille,int ligne, int col, unsigned char val)
     { int i,j,k;
         
       if (grille[ligne][col][0]==0 && val!=0)
        { grille[ligne][col][0] = val;
          for (k=0;k<MAX;k++)
            { printf("ETAPE 2\n");
              grille[ligne][k][val] = 0;
              grille[k][col][val] = 0;
            }
          for (i = (ligne/3*3); i <= (ligne/3*3) + 2; i++)
            { for (j = (col/3*3); j <= (col/3*3) + 2; j++)
                { printf("ETAPE 3\n");
                  grille[i][j][val]=0;
                }
            }
          for ( k=1; k<MAX+1;k++)
            grille[ligne][col][k] = k == val;
            printf("ETAPE 4\n");
         }
     }

  8. #68
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 45
    Par défaut
    Sa marche

    Je pense pour la deuxième règle, de comparais 3 ligne entre elles.
    Si un chiffre est présent de fois, regarder si on peut pas le mettre dans une case de la ligne ou il n'est pas présent, non ?

  9. #69
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    On peut rappeler la règle 1 utilisée pour récapituler avant de passer à la suivante :

    Règle1 : Si une seule valeur est possible pour la case (i,j), alors elle est certaine.
    En pratique cela conduisait à chercher les cases (i,j) pour lesquelles grille[i][j][k] , k=1..9 ne comportait qu'un seul 1.

    Avant de passer à des règles plus ésotériques, je te propose la règle suivante :

    Règle2 : si une valeur n'est possible qu'en une seule position d'une ligne, ou d'une colonne, ou d'un carré, alors elle est certaine.

  10. #70
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 45
    Par défaut
    oui ok,

    Donc je vais commencer par compter combien il y a de 0 pour chaque ligne ? si il en a que 1 je peut retourner 1 sinon je retourne 0. Si il retourne 0, on change de ligne car celle ci comporte plusieurs case vide.

  11. #71
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Non, tu n'as pas compris la règle.

    Si dans la ligne i, il y a une valeur V qui n'est possible qu'à la seule colonne j, alors grille[i][j] = V

    idem pour les colonnes et les carrés

  12. #72
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 45
    Par défaut
    Ah, ok. Un peu plus complexe que la première règle, pour modifier la case je fais toujours appelle a la procedure ChangeCase ?

  13. #73
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    pour modifier la case je fais toujours appelle a la procedure ChangeCase ?
    Absolument. Dans l'optique de ce programme, la seule manière de modifier une case doit être par appel de cette fonction. Sinon, on va se retrouver rapidement avec des données incohérentes.

  14. #74
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 45
    Par défaut
    J'ai un peu de mal a comprendre ceci dans la règle 1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
           if(res == -1) return -1;
           mod = mod || res == 1;
    mod = mod ou res = 1 ?

  15. #75
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Si res est égal à -1, alors une impossibilité a été détectée et on retoune cette information
    || est le OU logique et l'expression peut aussi s'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mod = mod || (res == 1);
    mod doit indiquer si au moins une modification a été apportée à la grille, c'est à dire si res a été égal à 1 au moins une fois.

    Au départ, mod est à 0 (0 signifie Faux : pas de modification)
    Si une modification est faite, res==1 est Vrai et mod = Faux OU Vrai -> mod devient Vrai (donc égal à 1)
    Ensuite, quelle que soit le résultat de res==1, Vrai ou Faux, on aura mod = Vrai
    Le résultat est le même ici que si on écrivait

  16. #76
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 45
    Par défaut
    ok ok merci pour les explication

  17. #77
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 45
    Par défaut
    Je pense que je ne n'aurais malheureusement pas le temps de terminer se projet, car aujourd'hui j'ai appris que je devais rendre le rapport Mercredi et non Vendredi avec la soutenance...
    N'ayant pas encore fais le rapport je dois laisser de coté le projet, pour pouvoir le commencer.

    Merci de l'aide

  18. #78
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 45
    Par défaut
    Bonjour,

    J'ai une petite question, comment faire pour lire un ficher contenant des lettres et des chiffres ?

  19. #79
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,


    Citation Envoyé par raining-blood Voir le message
    Bonjour,

    J'ai une petite question, comment faire pour lire un ficher contenant des lettres et des chiffres ?
    On peut lire le fichier caractère à caractère :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdio.h>
    #include <ctype.h>
    FILE f = fopen(..., "r");
    int c;
    do {
        c = fgetc(f);
        if(isdigit(c)) {
            printf("on a lu un chiffre\n");
        } else if(isalpha(c)) {
            printf("on a lu une lettre\n");
        } else {
            printf("on a lu autre chose...\n");
        }
    } while (EOF != c);
    Cela dit, il faut adapter la lecture au type de fichier à lire et à l'utilisation que tu veux en faire.

  20. #80
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 45
    Par défaut
    Le fichier lu est un .dat, les lettres et le chiffres vont être utiliser pour afficher une grille de 16x16 et de 25x25 par la suite, donc il seront ranger dans un tableau.

Discussions similaires

  1. Mettre a jour BD avec fichier csv
    Par Looping94510 dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 07/02/2005, 18h56
  2. Erreur avec fichier .manifest
    Par engi dans le forum Windows
    Réponses: 2
    Dernier message: 16/11/2004, 14h58
  3. [Eclipe 2.1.1]Projet avec fichiers sources existants
    Par mfofana dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 26/02/2004, 05h20
  4. Problème avec fichier texte
    Par jpdelx dans le forum ASP
    Réponses: 7
    Dernier message: 13/11/2003, 13h17
  5. Réponses: 4
    Dernier message: 25/08/2003, 09h02

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