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

Python Discussion :

Carré Magique (et boucles for)


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Par défaut Carré Magique (et boucles for)
    Bonjour,

    Je vous expose le problème :
    Un carré magique est une grille carrée dans laquelle des nombres sont placés de telle sorte que la somme des nombres de chaque colonne, chaque ligne et de chacune des deux diagonales soit la même. De plus, Le carré doit contenir une fois chaque nombre, de 1 au nombre de cases de la grille.
    Ecrivez un programme qui vérifie si une grille de nombres est un carré magique.

    La première ligne de l'entrée contient un entier N : le nombre de cases du côté de la grille de nombres.
    Chacune des N lignes suivantes contient N entiers séparés par des espaces : les nombres d'une ligne de la grille.

    Vous devez afficher une ligne sur la sortie, contenant le mot "yes" si le carré fourni est un carré magique, et "no" sinon.
    Donc.....
    La somme des lignes, c'est facile.
    Par contre, vérifier les sommes des colonnes et des diagonales.....là c'est déjà bien plus compliqué.

    Je vous colle ce que j'ai pour l'instant :
    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
    nbCases = int(input())
    carre = [[0] * nbCases for _ in range(nbCases)]
     
     
    for lig in range(nbCases) :
       lignes,colonnes,diag = 0,0,0
       carre[lig] = list(map(int,input().split()))
       for col in range(nbCases) :
     
          lignes += carre[lig][col]
          colonnes += carre[col][lig]
          diag += carre[lig][lig]
       print(diag,colonnes,lignes)
       if lignes == colonnes == diag :
          magique = True
       else :
          magique = False
     
    verif = 0
     
    for nbre in range(1,nbCases**2 + 1) :
       for lignes in carre :
          if nbre in lignes :
             verif += 1
     
     
    if magique and verif == nbCases**2:
       print('yes')
    else : 
       print('no')
     
    print(magique,verif)
    Marche pas. Je ne sais vraiment pas comment m'y prendre.
    Déjà, est-ce que la somme des colonnes et des diagonales du carré se font bien dans des boucles for ?
    (oui, forcément. Mais comment ? )

    D'avance merci pour vos éclairages

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
          lignes += carre[lig][col]
          colonnes += carre[col][lig]
          diag += carre[lig][lig]
    C'est très laid ca. Et pas étonnant que ca conduise à vous emmelez les pinceaux !

    Etape 1: Construisez votre variable carre, à partir de l'input utilisateur. Faites ensuite afficher ce carré pour vérifier qu'il y ait bien ce qu'il faut dedans. Ne faites rien d'autre.
    Etape 2 : Maintenant que vous avez la donnée dans une structure python vous aller la traiter. Le traitement du problème est à découper en plusieurs étapes comme il l'est clairement indiquer aussi dans l'énoncé :
    - somme des lignes
    - somme des colonnes
    - somme des diagonales
    - unicité de chaque nombre sur chaque ligne
    - unicité de chaque nombre sur chaque colonne
    - unicité de chaque nombre sur chaque diagonale

    Vous pourrez surment fusionner une partie des traitements, mais faites le d'abord en 6 sous traitement. Quand cela fonctionnera vous pourrez cherchez à optimiser.

    Indice pour les sommes : il faut jouer avec les indices.
    Somme de la 1ere diagonale par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sum = 0
    for k in range(nbCases):
       sum += carre[k][k]
    Somme de la i-ième colonne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sum = 0
    for k in range(nbCases):
       sum += carre[k][i]

    D'ailleurs le nom de la variable nbCases est assez mal choisi, puisqu'il s'agit en fait du nombre de lignes et de colonnes, mais pas du nombre de cases !

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    Citation Envoyé par RowanMayfair Voir le message
    Marche pas. Je ne sais vraiment pas comment m'y prendre.
    Écrivez votre tableau sur une feuille de papier.

    Comment allez vous vérifier, à la main, que c'est un carré magique?

    Essayez de réfléchir à comment vous vous y prenez: par où vous commencez, quelles en sont les différentes étapes,...

    Une fois que ce sera plus clair vous aurez une idée de quoi programmer pour automatiser cela.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre éclairé Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Par défaut
    Merci pour vos précieux conseils.
    Donc je suis repartie de 0, en y allant progressivement, et ensuite j'ai fait un peu de compactage.

    J'arrive à ça :
    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
    nbCases = int(input())
    carre = [[0] * nbCases for _ in range(nbCases)]
     
    carre = [list(map(int,input().split())) for lig in range(nbCases)]
     
    lignes,colonnes = [0] * nbCases, [0] * nbCases
     
    diag1, diag2 = 0,0
     
    for lig in range(nbCases) :
       diag1 += carre[lig][lig]
       diag2 += carre[lig][nbCases - 1 - lig]
       for col in range(nbCases) : 
          lignes[lig] += carre[lig][col]
          colonnes[lig] += carre[col][lig]
     
     
    if lignes == colonnes and len(set(lignes)) == 1 and diag1 == diag2 == lignes[0] :
       magique = True
    else :
       magique = False
     
     
     
    verif = 0
     
    for nbre in range(1,nbCases**2 + 1) :
       for lignes in carre :
          if nbre in lignes :
             verif += 1
     
    if magique and verif == nbCases**2 :
       print('yes')
    else : 
       print('no')
    Le code peut surement être beaucoup amélioré.

    Il est....presque bon.
    Il réussit 20 tests / 21. Il y a donc un cas de figure dans lequel il ne donne pas la réponde attendue.
    Je ne sais pas lequel évidemment , ce serait trop facile si on me le disait

  5. #5
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if lignes == colonnes and len(set(lignes)) == 1 and diag1 == diag2 == lignes[0] :
    Ici vous vérifiez :
    Que la somme des lignes est bien la meme que celles sur les colonnes, puis que la somme de toutes les lignes est identique, puis que la somme des diagonales est la meme et identique à celle de la 1ere lignes. OK, donc toute les sommes sont les mêmes. Mais est ce les bonnes ? Qu'est censé être la valeur somme d'une ligne ?

    Ensuite, ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for nbre in range(1,nbCases**2 + 1) :
       for lignes in carre :
          if nbre in lignes :
             verif += 1
    puis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if [...] verif == nbCases**2
    ne permet pas de vérifier que vous avez exactement les chiffres de 1 à n dans chaque ligne, colonne, et diagonale !
    Déjà rien interdit d'avoir une ligne comme ça (2 2 3 3 plutot qu'une ligne correcte de meme somme qui serait 1 2 3 4). Et ensuite vous ne faite pas de vérif ligne par ligne, ni colonne par colonne, ni sur les diagonales ! Enfin si nbCases (dont vous n'avez toujours pas changé le nom) vaut 3 par exemple, alors nbCases**2 + 1 vaut 10, et dans ce cas, pourquoi est ce qu'une ligne devrait contenir 9 ? Vous n'etes censé n'avoir que les nombre de 1 à nbCase inclus !

  6. #6
    Membre éclairé Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Par défaut
    Je n'ai pas changé mon nom de variable, parce que nbCases c'est le nombre de cases pour chaque ligne. Enfin vu que c'est un carré, nbCases est en fait le nombre de cases pour chaque côté du carré.

    Pour que le carré soit magique, il faut "seulement" que toutes les sommes soient les mêmes.
    Donc..... :
    - les sommes des lignes == sommes des colonnes
    - les sommes des lignes sont toutes les mêmes (donc les sommes des colonnes)
    - du coup, si les sommes des diagonales sont égales à l'une des sommes (lignes ou colonnes, peu importe), on est OK non ?
    Là, toutes les sommes sont les mêmes, donc on est bien parti pour le carré magique

    Et en effet, ça pêche pour la vérification de mes nombres.
    Je dois donc avoir, dans mon tableau, tous les nombres entre 1 et le nbre de cases du carré.
    Si mon carré a 4 lignes, alors j'ai 16 cases : nbCases **2
    Et je dois avoir tous les nombres entre 1 et 16.

    Chez moi ça n'allait pas, parce que si j'avais 2 fois le nbre 2 sur une ligne, ce n'était pas détecté.
    J'ai donc modifié ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    verif = []
     
    for nbre in range(1,nbCases**2 + 1) :
       for lignes in carre :
          if nbre in lignes and nbre not in verif :
             verif.append(nbre)
     
     
    if magique and len(verif) == nbCases**2 :
       print('yes')
    else : 
       print('no')
    et là Oh Miracle, Enfin, ça fonctionne parfaitement

    Mais alors y a des trucs pas très beaux, je vais aller étudier la correction, c'est surement plus beau que mon boulot

  7. #7
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Pour la vérification des sommes, les sommes doivent être toute égale, mais aussi égale à une valeur précise, qui dépend de la taille de votre grille. Après certes vous n'avez pas à le vérifier si derrière vous vérifier que vous avez bien tous les nbombres de 1 à nbCases**2.

    Pour faire cette dernière vérification vous auriez pu utiliser les set puisque vous sembler les connaitre !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    set( nbr for ligne in carre for nbr in ligne ) == set(range(1,nbCases**2 + 1))

Discussions similaires

  1. Boucle for dans un script cmd
    Par nicolas.ganache dans le forum Développement
    Réponses: 4
    Dernier message: 19/07/2004, 16h07
  2. Réponses: 3
    Dernier message: 06/07/2004, 10h21
  3. [Debutant] Batch et Boucle for
    Par ludovic.fernandez dans le forum Scripts/Batch
    Réponses: 8
    Dernier message: 06/05/2004, 19h21
  4. [Swing][boucles] for, do, if .....comment faire simple?
    Par chastel dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 02/05/2004, 22h49
  5. [langage] boucle "for" modification du pas
    Par K-ZimiR dans le forum Langage
    Réponses: 4
    Dernier message: 29/04/2004, 11h54

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