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 :

Memory error sur un script de résolution de labyrinthe


Sujet :

Python

  1. #21
    Invité
    Invité(e)
    Par défaut
    Bon, un truc qui semble marcher, à force de tâtonnement

    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
    def get_all_valide_cases(pos,pcd,k):
        x, y = pos
        poles = [(x+i, y+I) for i in range(-1,2) for I in range(-1,2) if (i,I) != (0, 0) and (not i or not I)]
     
        liste = []
        k+=1
        for X, Y in poles:
            if X < 0 and Y <0:
                continue
            if (X, Y) != pcd :
                try:
                    if area[X][Y]==1 or area[X][Y]>k:
                       liste.append([X, Y, k])
                except IndexError:
                    pass
     
        return liste
     
    def next_step(x1, y1, pcds, k1=2):
        liste = []
        liste.append((x1, y1, k1))
        pcd = pcds
        while liste:
            x, y, k = liste.pop()
            bifs = get_all_valide_cases((x, y), pcd, k)
            liste.extend(bifs)
            area[x][y]=k
            print_area(area,(x,y))
    Montage vidéo de qualité ! 🙃


    PS :
    Bon j'ai arrêté là le carnage, 2h pour seulement la moitié des chemins !!!

    Une idée de la taille du bousin :
    Nom : extrait maze.JPG
Affichages : 184
Taille : 653,9 Ko
    A gauche on voit que le labyrinthe est encore inexploré, plus on descend plus la partie gauche est inexplorée (dû à la particularité des labyrinthes Sidewinder)

    Le début du labyrinthe !!! Enorme !!! Un détour de 38630 cases pour arriver à 5 cases du départ, sachant que l'arrivée se trouve à maximum 48919 cases ! Cet enfer me plait bien !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        0,    1,    0,    0,    0,    0,    0,    0,
        0,    2,    3,    4,    5,38630,38629,38628,
        0,    3,    0,    0,    6,    0,    0,    0,
        0,    4,    0,    0,    7,    0,    0,    0,
        0,    5,    0,    0,    8,    9,   10,   11,
    Dernière modification par Invité ; 03/01/2022 à 19h37.

  2. #22
    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
    Il existerait plein de moyen d'optimiser une exploration brutale pour des gros labyrinthe.

    Déjà vous pouvez vous dire qu'en entame vous faites 1 exploration main gauche, ET, une exploration main droite. Je l'es appelle G et D dans la suite.
    Là, si les 2 explorations G et D donnent le même résultat (G=D), alors il existe un seul et unique chemin, et donc c'est forcément le plus court. Sinon, vous pouvez enlever toutes les parties communes de ces 2 explorations, et ensuite relancer une exploration plus approfondie, mais seulement à l'intérieure de la zone défini par ces 2 chemins.

    Il se peut d'ailleurs que vous ayez des solutions par morceau : G et D coincide, sur une partie, puis se distingue, puis à nouveau coïncide, puis à nouveau se distingue avant de recoincider à la fin. Et on peut imaginer autant de morceau que l'on veut. Mais indépendamment du nombre de morceau, vous pouvez ensuite étudier 1 par 1 chaque morceau, comme si chaque morceau constituait un labyrinthe à lui seul, et chaque morceau sera beaucoup moins complexe que le labyrinthe tout entier !

    Ensuite on peut chercher également à optimiser le traitement de chaque morceaux. Par exemple, une idée comme ca (à étudier/vérifier, je balance une idée comme ca), serait de se dire : ok G et D diffère. Si je bouche le pan de mur de G, à l'endroit ou G et D diffère, et que je refais un main gauche avec cette nouvelle config ? Disons que ce que j'obtiens c'est donc un G'. Là si G' = D, alors je reviens au problème de départ, et donc G et D sont les 2 seuls chemins possibles, me reste juste à dire lequel de ces 2 là est le plus court. Si G' est différent de D, alors j'ai trouvé un 3ième chemin possible en plus de G et D. Et je peux ainsi recommencer le raisonnement entre G' et D, en calculant un G'', pour voir si je n'ai pas un 4ieme chemin, etc ... Et une fois identifié tous les chemins possible, dire lequel est le plus court.

    En règle général il est impossible de gagner sur les 2 tableaux que sont mémoire et temps de calcul.
    1) Soit vous explorez le labyrinthe en stockant dans un arbre toutes les possibilités rencontrées à chaque noeud. C'est ce qui va être le plus rapide pour la recherche du chemin le plus court, mais qui va prendre le plus de mémoire. Vous pouvez éventuellement élaguer l'arbre dès que vous tombez dans un cul de sac pour libérer de la mémoire.
    2) Soit vous mémorisez des chemins, et donc dans ce cas là, vous ne stockez pas grand chose en mémoire, mais vous risquez fortement de devoir visiter plusieurs fois la même case au cours de votre processus de recherche, et donc le temps de calcul va être plus long.

    Il y a mille et une manière de faire. Ce serait pas mal de fournir un labyrinthe pas trop gros, histoire qu'on puisse tester votre code, avec un temps d'exécution de moins d'une minute. Mais déjà, ca permettrait de monitorer les choses sur cet exemple. Implémenter plusieurs algos, et regarder les performances en temps de calcul et RAM utilisée. Ca permettrait:
    1) d'avoir une idée du temps de calcul pour un gros labyrinthe (et de savoir si ca passe en RAM ou non)
    2) de pouvoir faire des optimisations sur un truc qui met pas 2H à tourner (sinon c'est un peu galère)

    Lg53

  3. #23
    Invité
    Invité(e)
    Par défaut
    Salut lg_53 !

    Désolé par avance si mon post pose problème, n'hésitez pas à l'éditer si des modérateurs passent par là !!!

    Voici un exemple (150*150) que j'ai complexifié à la main pour ressembler très vaguement à ce que j'ai fait ...
    0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
    0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0
    0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0
    0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0
    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0
    0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0
    0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0
    0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0
    0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0
    0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0
    0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0
    0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0
    0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
    0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
    0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
    0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0
    0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0
    0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0
    0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0
    0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0
    0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0
    0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0
    0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0
    0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0
    0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0
    0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0
    0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0
    0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0
    0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0
    0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0
    0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0
    0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0
    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0
    0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0
    0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0
    0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0
    0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
    0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0
    0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0
    0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0
    0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0
    0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0
    0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0
    0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0
    0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0
    0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0
    0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0
    0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0
    0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0
    0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0
    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0
    0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0
    0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0
    0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0
    0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0
    0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0
    0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0
    0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0
    0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0
    0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0
    0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0
    0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0
    0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0
    0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0
    0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0
    0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0
    0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0
    0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0
    0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
    0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0
    0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0
    0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0
    0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0
    0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0
    0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0
    0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0
    0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0
    0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0
    0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0
    0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0
    0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
    0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0
    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0
    0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0
    0,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0
    0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0
    0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,1,1,0
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0


    Mon script est pas mal du tout :
    En 0.05 secondes il trouve le chemin !

    Une partie en image :
    Nom : extrait image dev.jpg
Affichages : 164
Taille : 1,22 Mo

    Il serait intéressant que je le complexifie d'avantage en faisant en sorte que le chemin remonte de temps en temps pour mimer un peu mieux le gros labyrinthe...

    Le script en chantier, si vous voulez vous amuser avec :
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    file = open("EXAMPLE FOR DEVELOPPEZ.NET.txt","r")
    area = file.read().replace(',','').splitlines()
    file.close()
    air = [[1 if int(x) else 0 for x in line] for line in area]
     
    import sys, time
    from tkinter import * 
    import tkinter.font as font
    print(time.ctime())
    st = time.time()
    #time.sleep(3)
    #sys.setrecursionlimit(1030)
     
    '''air = [[0,1,0,0,0,0,0,0,0],
            [0,1,0,0,1,1,1,1,0],
            [0,1,0,1,1,0,0,1,0],
            [0,1,1,1,0,1,1,1,0],
            [0,1,0,0,0,1,0,1,0],
            [0,1,1,1,1,1,1,1,0],
            [0,1,0,1,0,0,0,1,0],
            [0,0,0,0,0,0,0,1,0]]'''
     
    area = [l.copy() for l in air]
     
    start = (0,1)
    end = (len(area)-1,len(area[-1])-2)
     
    def rgbtohex(r,g,b):
        return f'#{r:02x}{g:02x}{b:02x}'
     
    def print_area(tableau,pos):
        #for line in tableau:
         #   print(['{:02}'.format(x) for x in line])
        #print('---------------\n')
       # time.sleep(0.5)
        for line in range(len(area)):
            for col in range(len(area[0])):
                if tableau[line][col]>1 or (line == start[0] and col == start[1]):
                    button = table[line][col]
                    button.configure(bg=rgbtohex(0, 255-tableau[line][col]*8 ,0))
                    button.configure(text=str(tableau[line][col]))
                    c = "BLACK"
                    if (255-tableau[line][col]*10) < 100:
                        c = "WHITE"
                    button.configure(fg=c)
                    if pos == (line,col):
                        time.sleep(0.2)
                        button.configure(bg=rgbtohex(235, 50, 10))
                        root.update()
                        time.sleep(0.2)
                        button.configure(bg=rgbtohex(0, 255-tableau[line][col]*8 ,0))
                        root.update()
        #time.sleep(0.2)
        root.update()
     
    path = []
    def find_way(x, y):
        global path
        path.append((x, y))
        for X, Y in ((x+i, y+I) for i in range(-1,2) for I in range(-1,2) if (i,I) != (0, 0) and (not i or not I)):
            try:
                if area[X][Y]==area[x][y]-1 and X >= 0 and Y >= 0 and area[X][Y]:            
                    find_way(X, Y)
                    break
            except IndexError:
                print("error",X,Y)
     
    #visited = []
    #def next_step(x,y,pcds,k=2):#visited,k=2):
    #    global visited
    #    #visited_copy = visited.copy()
    #    for X, Y in ((x+i, y+I) for i in range(-1,2) for I in range(-1,2) if (i,I) != (0, 0) and (not i or not I)):
    #        if X < 0 and Y <0:
    #            continue
    #        if (X, Y) != pcds :
    #            try:
    #                if area[X][Y]==1 or area[X][Y]>k:
    #                    #if (X,Y) not in visited_copy:
    #                    #    visited_copy.append(pcds)
    #                    visited.append((X,Y))
    #                    area[X][Y]=k
    #                    #print_area(area,(X,Y))                    
    #                    next_step(X,Y,(x, y),k+1)#visited_copy,k+1)                    
    #            except IndexError:
    #                print('bug :',X,Y)
    #                pass
    #            except RecursionError:
    #                counter = 0
    #                for x in visited:
    #                    count = visited.count(x)
    #                    if count > counter:
    #                        counter = count
    #                print('counter',counter)
     
    def get_all_valide_cases(pos,pcd,k):
        x, y = pos
        poles = [(x+i, y+I) for i in range(-1,2) for I in range(-1,2) if (i,I) != (0, 0) and (not i or not I)]
     
        liste = []
        k+=1
        for X, Y in poles:
            if X < 0 and Y <0:
                continue
            if (X, Y) != pcd :
                try:
                    if area[X][Y]==1 or area[X][Y]>k:
                       liste.append([X, Y, k])
                except IndexError:
                    pass
        #if liste:
         #   liste[-1][2]+=1
     
        return liste
     
    def next_step(x1, y1, pcds, k1=1):
        liste = []
        liste.append((x1, y1, k1))
        pcd = pcds
        while liste:
            x, y, k = liste.pop()
            bifs = get_all_valide_cases((x, y), pcd, k)
            liste.extend(bifs)
            area[x][y]=k
            #print_area(area,(x,y))
     
    '''root = Tk()
    myFont = font.Font(size=30)
    table = []
    for line in range(len(area)):
            ligne = []
            for col in range(len(area[0])):
                color = "GREY"
                if area[line][col]:
                    color = "WHITE"
                button = Button(root, text=str(area[line][col]), borderwidth=1,  width = 5, height = 1, bg=color, font=myFont)
                button.grid(row=line, column=col)
                ligne.append(button)
            table.append(ligne)
     
     
    root.update()
    time.sleep(5)'''
     
     
    next_step(start[0], start[1], start)
    '''print(area[-5][-15:])
    print(area[-4][-15:])
    print(area[-3][-15:])
    print(area[-2][-15:])
    print(area[-1][-15:])'''
    find_way(end[0], end[1])
     
    '''for X, Y in path:
        button = table[X][Y]
        button.configure(bg=rgbtohex(148,255,0))
        time.sleep(0.1)
        root.update()
    root.mainloop()'''
    #print_area(air)
    #print_area(area)
    #find_way(end[0], end[1])
    for x, y in path:
        air[x][y] = 9
    #print_area(air)
     
    with open("EXAMPLE FOR DEVELOPPEZ.NET_SOLVED.txt","w") as file:
        for line in air:
            file.write(str(line)[1:-1].replace(' ',''))
            file.write('\n')
     
    print('durée :',time.time()-st)

  4. #24
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 817
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Le script en chantier, si vous voulez vous amuser avec
    Il faudrait essayer de changer tes habitudes d'appeler tes variables "liste". Déjà parce que ça peut amener une confusion avec le type "list()" et bon ça aide pas à comprendre de quoi est faite la liste.
    Et ensuite supprimer toutes les instructions situées "hors fonction" (ou autrement dit, tout mettre en fonction). Tu y gagneras en mobilité et en évolutivité (et aussi en lisibilité). Donc une fonction main() qui commence le travail et de là...

    Citation Envoyé par LeNarvalo Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    liste = []
    liste.append((x1, y1, k1))

    liste=[(x1, y1, k1),].

    Citation Envoyé par LeNarvalo Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for line in air:
    	file.write(str(line)[1:-1].replace(' ',''))
    	file.write('\n')
    Ca c'est horrible(*). Tu te bases sur le fait que l'affichage d'un tableau sous forme str affichera les crochets en position 0 et -1. Donc tu les effaces. Bref tu utilises une donnée transformée via un formalisme d'affichage pour obtenir un résultat. Et si demain le formalisme change? Et heureusement qu'il y a une virgule dans l'affichage par défaut car justement tu voulais une virgule. Mais si demain tu veux un tiret???
    Tu as la donnée de base, utilise là telle quelle et transforme là à ta manière pour obtenir le résultat attendu
    for line in air: print(",".join(map(str, line)), file=file).

    (*) ce qui est amusant, c'est que je faisais la même chose à mes débuts
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #25
    Invité
    Invité(e)
    Par défaut
    Oui c'est un script dégueulasse, pour le moment, je veux que ça marche et assez vite si possible.

    Citation Envoyé par Sve@r Voir le message
    liste=[(x1, y1, k1),].
    Effectivement, à la base je voulais sûrement pas rajouter ce tuple avant le while, je suppose, je me rappelle plus... Bref, j'ai du déplacer le liste.append(...) je pense. Sinon tkt je ne me trompe pas entre list() et liste, il m'arrive même d'utiliser LISTE mais pas LIST par contre...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for line in air:
    	file.write(str(line)[1:-1].replace(' ',''))
    	file.write('\n')
    Ca c'est horrible(*).
    Oui mais :
    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
    >>> import time
    >>> l = [[i for i in range(10**4)] for _ in range(10**4)]
    >>> def test1():
    	st = time.time()
    	with open(r"C:\Users\toto\Desktop\TOTO1.txt","w") as file:
    		for line in l:
    			file.write(str(line)[1:-1].replace(' ',''))
    			file.write('\n')
    	print(time.time()-st)
     
     
    >>> def test2():
    	st = time.time()
    	with open(r"C:\Users\toto\Desktop\TOTO2.txt","w") as file:
    		for line in l:
    			print(",".join(map(str, line)), file=file)
    	print(time.time()-st)
     
    >>> test2()
    14.255894184112549
    >>> test1()
    9.353563785552979
    >>> test1()
    9.434396028518677
    >>> test2()
    14.044034481048584

    Comme quoi string.replace() est super efficace !
    Dernière modification par Invité ; 05/01/2022 à 20h14.

  6. #26
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 198
    Par défaut
    hello,
    Citation Envoyé par LeNarvalo Voir le message
    Il serait intéressant que je le complexifie d'avantage en faisant en sorte que le chemin remonte de temps en temps pour mimer un peu mieux le gros labyrinthe...
    Pour cela tu peux utiliser le générateur de labyrinthe de PathFinder dont je parle ici. J'ai rajouté à PathFinder un bouton qui sauvegarde le labyrinthe affiché dans un fichier texte (maze.txt) compatible avec ton solveur de labyrinthe. Pour avoir le point d'entrée et le point de sortie du labyrinthe généré, il faut cliquer droit sur les cases concernées ce qui blanchit la case (passe à 1).
    Voici ce que cela donne avec un labyrinthe de 50x50 DFS généré qui contient des remontées :

    Nom : PathFinderAStarSolver2.PNG
Affichages : 145
Taille : 124,1 Ko

    La résolution a été effectuée par l'algorithme A*

    et voici ce que donne la résolution du même labyrinthe avec ton script :
    Nom : ResultatLeNarvalo.PNG
Affichages : 142
Taille : 47,3 Ko


    On constate que le même chemin a été trouvé

    En pièce jointe, le script PathFinder modifié avec ajout du bouton Save maze et le fichier maze.txt généré dans le test ci-dessus.
    Voici le code du bouton Save Maze ajouté :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
                    elif options[1].is_hover(pos):
                        with open("maze.txt", "w") as file:
                            for i  in range(len(grid)):
                                line=''
                                for j in range(len(grid[i])):
                                    if grid[j][i].is_barrier():
                                        line += '0,'
                                    else:
                                        line += '1,'
                                print(line)
                                file.write(str(line)[:-1] + '\n')
    A noter que le positionnement des boutons dans le script PathFinder est assez "merdique" et mériterait sans doute une révision (avec un autre type de gestion de positionnement).
    Je ne sais pas si c'est facilement faisable, mais LeNarvalo tu pourrais peut-être ajouté ton algo dans le script.

    Ami calmant, J.P
    Fichiers attachés Fichiers attachés

  7. #27
    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
    Autre conseil :

    - Au début de code, il est mieux de lire le fichier comme ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    with open("EXAMPLE FOR DEVELOPPEZ.NET.txt","r") as fp :
        area = fp.read().replace(',','').splitlines()
    Et d'ailleurs comme tout bon programmeur qui se respecte vous ne devriiez JAMAIS mettre des espaces dans des noms de fichiers ou de dossier ...

    - Je vois un mot clé "global" ... pas bien. Vous devez absolument faire sans. Il faut faire avec des paramètres et des return. On n'écrit pas le résultat dans un truc global, de même on va pas chercher un paramètre dans un truc global. Tout doit etre spécifier à l'échelle de la fonction.

    - Non ! Oui ! Et après vous écrivez tk.blabla, ce qui fait 3 caractères de plus, mais au moins si vous tombez sur une méthode que vous ne connaissez pas, et bien vous savez là, qu'elle vient de tktinter. De même imaginé que vous chargiez d'autre package avec le *, et qu'un autre package définisse lui aussi une fonction portant le même nom qu'un fonction tkinter que vous utilisez. Il va se passer quoi là d'après vous ? Rien de bon, donc il faut proscrire le import *.

    - Ca m'aurait bien dit de jouer un peu avec votre code, mais là comme il n'y a pas de contrôle entre guillemet, je modifie des trucs, ca tourne, mais je ne sais pas si le code fournit toujours le résultat attendu. D'autant plus que là vous semblez avoir désactiver l'interface graphique, donc je fais tourner et modifie des trucs en aveugle. Mettez un paramètre en début de code, pour savoir si vous voulez faire tourner avec ou sans chronométrage, avec ou sans interface graphique.
    Après avoir fait ca, définir un contrôle, ca veut dire avoir un fichier en plus, dans lequel le chemin de réponse est stockée. à chaque exécution vous allez lire ce fichier, vous comparez à ce que vous venez de calculer, et si vous avez une différence vous mettez une erreur bien visible (voire même mieux, une exception qui sauterait direct au nez), de sorte à détecter immédiatement si la modif que vous avez faites impacte ou non sur le résultat attendu.

  8. #28
    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
    for X, Y in ((x+i, y+I) for i in range(-1,2) for I in range(-1,2) if (i,I) != (0, 0) and (not i or not I)):
    Sérieu ? Tout ca pour dire que vous regardez les 4 positions autour de la position courante ?
    Et comme ca c'est pas plus clair :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for X, Y in ((x-1, y),(x,y-1),(x,y+1),(x+1,y)):
    ?

  9. #29
    Invité
    Invité(e)
    Par défaut
    Salut !
    @jurassic pork +2 pour le boulot !

    Je ne pense pas utiliser le script que tu as modifié pour tester mon script de résolution, je ne vois pas trop l'intérêt, j'ai déjà ma version simplifiée pour visualiser la chose avec Tkinter... Et puis je sais que si je me lance là dedans je vais y passer 15 jours ! Par contre c'est très beau et ça va mettre utile pour tester mon script en sauvegardant en fichier txt.


    @lg_53 Merci d'avoir zyeuté le bouzin ! Au sujet de global, en plus il ne sert à rien. Je dois passer cette fonction en mode "pile" plutôt que récursive de toute manière car le chemin est trop long...

    Au sujet des from tkinter import * oui ça aussi je sais que ce n'est pas bien, mais j'avoue que c'est le cadet de mes soucis pour le moment, j'utilise ici Tkinter pour me permettre de visualiser la chose sur des petits exemples. Mais en effet ça peut poser problème notamment lorsqu'on utilise tkinter et tkinter.ttk en simultané...

    Au sujet de l'interface graphique, oui c'est le bazar total ! C'est même pas digne d'une version pre-alpha ! ^^

    Sinon effectivement il faudrait que je fasse une fonction de contrôle, peut-être à l'aide du script partagé par Jurrasic Pork... Je fais une petite pause.

  10. #30
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par lg_53 Voir le message
    Sérieu ? Tout ca pour dire que vous regardez les 4 positions autour de la position courante ?
    Et comme ca c'est pas plus clair :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for X, Y in ((x-1, y),(x,y-1),(x,y+1),(x+1,y)):
    ?
    Ah ah carrément !

    Nan mais parfois je pars dans des délires !!

    Y a la même ici : poles = [(x+i, y+I) for i in range(-1,2) for I in range(-1,2) if (i,I) != (0, 0) and (not i or not I)].

    Je reviens sur un truc :
    with open("EXAMPLE FOR DEVELOPPEZ.NET.txt","r") as fp :.
    C'est vraiment important pour le mode lecture ?
    Pour le mode écriture je savais mais je pensais que pour le mode lecture on ne risquait pas grand chose à utiliser file = open('...', 'r')
    Dernière modification par Invité ; 06/01/2022 à 17h31.

  11. #31
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 817
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Y a la même ici : poles = [(x+i, y+I) for i in range(-1,2) for I in range(-1,2) if (i,I) != (0, 0) and (not i or not I)].
    C'est vrai que j'ai lu cette ligne mais j'ai pas tenté de la déchiffrer. Bon le souci c'est que suis pas chez-moi dont j'ai pas ma machine avec un Python prêt à l'emploi pour tout tester de façon posée.
    Concernant tes chronos sur replace() par rapport à ma façon de faire effectivement c'est plus rapide (ai testé ton code sur un Python en ligne) mais je sais pas pourquoi, je continue à ne pas trouver ça super top.

    Citation Envoyé par LeNarvalo Voir le message
    Je reviens sur un truc :
    with open("EXAMPLE FOR DEVELOPPEZ.NET.txt","r") as fp :.
    C'est vraiment important pour le mode lecture ?
    Pour le mode écriture je savais mais je pensais que pour le mode lecture on ne risquait pas grand chose à utiliser file = open('...', 'r')
    En fait pas vraiment, un OS assez évolué se charge de fermer le fichier à la fermeture du programme (valable aussi pour le mode "w"). Mais déjà tu n'es pas sûr que ce sera valable sur tous les OS et surtout c'est une question d'habitude. Autant faire les choses correctement surtout si ça ne coûte pas plus cher.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  12. #32
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 699
    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 699
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Mais déjà tu n'es pas sûr que ce sera valable sur tous les OS et surtout c'est une question d'habitude. Autant faire les choses correctement surtout si ça ne coûte pas plus cher.
    Avec le with... le fichier ne reste ouvert qu'à l'intérieur du bloc associé et sera fermé dès qu'on en sort. L'intérêt est identique à celui de remplacer la construction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    i = 0
    while i < ...:
        ...
        i += 1
    par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i in range(...):
        ...
    Outre que c'est plus court, ça évite d'oublier d'incrémenter la variable de contrôle lorsqu'on s'endort sur le clavier... (avec with on est sur de faire un close sans l'écrire explicitement).

    Utiliser with... n'est pas plus correct qu'open/close. Ça facilite la relecture du code lorsqu'on a des soucis de mise au point car on n'a pas à se poser la question de savoir si le close sera exécuté. On est plus dans la logique "les bons risques sont ceux qu'on ne prend pas".

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

  13. #33
    Invité
    Invité(e)
    Par défaut
    Merci Wiz pour ces explications !




    J'ai fait un truc chiadé, c'est super envoutant de voir le comportement du script quand on rajoute des boucles !!! Je comprends mieux pourquoi il met autant de temps ! Mais je ne vois pas encore totalement comment m'y prendre pour être sûr de bien améliorer le script...

    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    import sys, time, threading
    from tkinter import * 
     
    with open("EXAMPLE FOR DEVELOPPEZ.NET.txt","r") as fp :
        area = fp.read().replace(',','').splitlines()
     
    air = [[1 if int(x) else 0 for x in line] for line in area]
     
    print(time.ctime())
    st = time.time()
     
    #Mode graphique :
    graph = True
     
    #Exemple :
    '''air = [[0,1,0,0,0,0,0,0,0],
                [0,1,0,0,1,1,1,1,0],
                [0,1,0,1,1,0,0,1,0],
                [0,1,1,1,0,1,1,1,0],
                [0,1,0,0,0,1,0,1,0],
                [0,1,1,1,1,1,1,1,0],
                [0,1,0,1,0,0,0,1,0],
                [0,0,0,0,0,0,0,1,0]]'''
     
     
    area = [l.copy() for l in air]
    start = (0,1)
    end = (len(area)-1,len(area[-1])-2)
     
    if graph and len(area)*len(area[0])>10000:
        print("TOO BIG FOR GRAPHICAL MODE")
        graph = False
     
    def color(rgb=(255,45,45)):
        r,g,b = rgb
        degrades = [(r,g,b)]
     
        while r == 255 and g < 255:
            g+=1
            degrades.append((r,g,b))
        while g == 255 and r > 45:
            r-=1
            degrades.append((r,g,b))
        while g == 255 and b < 255:
            b+=1
            degrades.append((r,g,b))
        while b == 255 and g > 45:
            g-=1
            degrades.append((r,g,b))
     
        colors = [degrades[i] for i in range(0,len(degrades),int(len(degrades)/(len(area)*3)))]
        sens = [i  for _ in range(50) for i in (-1,1)]
        colors = [color for i in sens for color in colors[::i]]
     
        return colors
     
    colors = color()
     
    def rgbtohex(r,g,b):
        return f'#{r:02x}{g:02x}{b:02x}'
     
     
    def print_area(tableau,pos):
        global sign
        x, y = pos
        r,g,b = colors[tableau[x][y]]
     
        button = table[x][y]
        button.configure(bg=rgbtohex(r, g ,b))
        button.configure(text=str(tableau[x][y]))
        c = "BLACK"
     
        if r+g+b < 255 :
            c = "WHITE"
        button.configure(fg=c)
     
        if pos == (x, y):
            time.sleep(0.01)
            button.configure(bg=rgbtohex(235, 50, 10))
            root.update()
            time.sleep(0.01)
            button.configure(bg=rgbtohex(r, g ,b))
            root.update()
     
        root.update()
     
    def find_way(x, y):
        path = [(x, y)]
        while path[-1] != start:
            for X, Y in ((x-1, y),(x,y-1),(x,y+1),(x+1,y)):
                try:
                    if area[X][Y]==area[x][y]-1 and X >= 0 and Y >= 0 and area[X][Y]:            
                        path.append((X, Y))
                        x,y = X, Y
                        break
                except IndexError:
                    print("error",X,Y)
     
        if graph:
            for X, Y in path:
                button = table[X][Y]
                button.configure(bg=rgbtohex(185,45,255), fg="BLACK")
                time.sleep(0.02)
                root.update()
     
        for x, y in path:
            air[x][y] = 9
     
        with open("EXAMPLE FOR DEVELOPPEZ.NET_SOLVED.txt","w") as file:
            for line in air:
                file.write(str(line)[1:-1].replace(' ',''))
                file.write('\n')
     
        print('durée :',time.time()-st)
     
    def get_all_valide_cases(pos,pcd,k):
        x, y = pos
        poles = [(x-1, y),(x,y-1),(x,y+1),(x+1,y)]
     
        next_cases = []
        k+=1
        for X, Y in poles:
            if X < 0 and Y <0:
                continue
            if (X, Y) != pcd :
                try:
                    if area[X][Y]==1 or area[X][Y]>k:
                       next_cases.append([X, Y, k])
                except IndexError:
                    pass
     
        return next_cases
     
    def main():
        path_to_go = [(start[0], start[1], 1)]
        pcd = start
        while path_to_go:
            x, y, k = path_to_go.pop()
            next_cases = get_all_valide_cases((x, y), pcd, k)
            path_to_go.extend(next_cases)
            area[x][y]=k
            if graph:
                print_area(area,(x,y))
     
        find_way(end[0], end[1])
     
    def refresh_scrollbar(event):
        root.update()
     
    def launch(event):
        threading.Thread(target=main).start()
     
    def escape(event):
        if root.attributes('-fullscreen'):
            root.attributes('-fullscreen', False)
            root.geometry(f'{root.winfo_screenwidth()-10}x{root.winfo_screenheight()-90}+0+0')
        else:
            root.destroy()
     
    def add(event):
        button = event.widget
        x, y = button.coords
        area[x][y]+=1
     
        r,g,b = colors[area[x][y]]
        bgcolor = rgbtohex(r,g,b)
        if area[x][y] == 1 :
            bgcolor = "WHITE"
        elif not area[x][y]:
            bgcolor = "GREY15"
     
        fgcolor = "BLACK"
        if not area[x][y]:
            fgcolor = "GREY50"
     
        button.configure(text=str(area[x][y]), bg=bgcolor, fg=fgcolor)
     
    def reduce(event):
        button = event.widget
        x, y = button.coords
        area[x][y]=max(0,area[x][y]-1)
     
        r,g,b = colors[area[x][y]]
        bgcolor = rgbtohex(r,g,b)
        if area[x][y] == 1 :
            bgcolor = "WHITE"
        elif not area[x][y]:
            bgcolor = "GREY15"
     
        fgcolor = "BLACK"
        if not area[x][y]:
            fgcolor = "GREY50"
     
        button.configure(text=str(area[x][y]), bg=bgcolor, fg=fgcolor)
     
     
    if graph:
        root = Tk()
        root.configure(bg="GREY15")
        root.attributes('-fullscreen', True)
        root.geometry(f'{root.winfo_screenwidth()}x{root.winfo_screenheight()}+0+0')
        vsb = Scrollbar(root, orient=VERTICAL)
        vsb.grid(row=0, column=1, sticky=N+S)
        vsb.bind('<Motion>',refresh_scrollbar)
        hsb = Scrollbar(root, orient=HORIZONTAL)
        hsb.grid(row=1, column=0, sticky=E+W)
        hsb.bind('<Motion>',refresh_scrollbar)
        c = Canvas(root,yscrollcommand=vsb.set, xscrollcommand=hsb.set,bg="GREY15")
        c.grid(row=0, column=0, sticky="news")
        vsb.config(command=c.yview)
        hsb.config(command=c.xview)
        root.grid_rowconfigure(0, weight=1)
        root.grid_columnconfigure(0, weight=1)
        fr = Frame(c,bg="GREY15")
        table = []
        for line in range(len(area)):
                ligne = []
                for col in range(len(area[0])):
                    bgcolor = "GREY15"
                    if area[line][col]:
                        bgcolor = "WHITE"
                    fgcolor = "BLACK"
                    if not area[line][col]:
                        fgcolor = "GREY50"
                    button = Button(fr, text=str(area[line][col]), borderwidth=1,  width = 3, height = 1, bg=bgcolor, fg=fgcolor)
                    button.grid(row=line, column=col)
                    button.coords = (line, col)
                    button.bind("<ButtonRelease-1>", add)
                    button.bind("<ButtonRelease-3>", reduce)
                    ligne.append(button)
                table.append(ligne)
        c.create_window(0, 0,  window=fr)    
        fr.update_idletasks()
        c.config(scrollregion=c.bbox("all"))
        c.xview_moveto(0.0)
        c.yview_moveto(0.0)
        root.update()
        root.bind('<Escape>', escape)
        root.bind('<Return>', launch)
        root.mainloop()
     
    else:
        main()

    Escape (Echap) une fois pour sortir du plein écran, deux fois pour quitter Tkinter
    Return (Entrée) pour lancer le script !

    Wow ! La différence de rapidité avec ces modifs :
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    import sys, time, threading
    from tkinter import * 
     
    with open("EXAMPLE FOR DEVELOPPEZ.NET_MODIFIED.txt","r") as fp :
        area = fp.read().replace(',','').splitlines()
     
    air = [[1 if int(x) else 0 for x in line] for line in area]
     
    print(time.ctime())
    st = time.time()
     
    #Mode graphique :
    graph = True
     
    #Exemple :
    '''air = [[0,1,0,0,0,0,0,0,0],
                [0,1,0,0,1,1,1,1,0],
                [0,1,0,1,1,0,0,1,0],
                [0,1,1,1,0,1,1,1,0],
                [0,1,0,0,0,1,0,1,0],
                [0,1,1,1,1,1,1,1,0],
                [0,1,0,1,0,0,0,1,0],
                [0,0,0,0,0,0,0,1,0]]'''
     
     
    area = [l.copy() for l in air]
    start = (0,1)
    end = (len(area)-1,len(area[-1])-2)
    maxi = 999999999
     
    if graph and len(area)*len(area[0])>10000:
        print("TOO BIG FOR GRAPHICAL MODE")
        graph = False
     
    def color(rgb=(255,45,45)):
        r,g,b = rgb
        degrades = [(r,g,b)]
     
        while r == 255 and g < 255:
            g+=1
            degrades.append((r,g,b))
        while g == 255 and r > 45:
            r-=1
            degrades.append((r,g,b))
        while g == 255 and b < 255:
            b+=1
            degrades.append((r,g,b))
        while b == 255 and g > 45:
            g-=1
            degrades.append((r,g,b))
     
        colors = [degrades[i] for i in range(0,len(degrades),int(len(degrades)/(len(area)*3)))]
        sens = [i  for _ in range(50) for i in (-1,1)]
        colors = [color for i in sens for color in colors[::i]]
     
        return colors
     
    colors = color()
     
    def rgbtohex(r,g,b):
        return f'#{r:02x}{g:02x}{b:02x}'
     
     
    def print_area(tableau,pos):
        global sign
        x, y = pos
        r,g,b = colors[tableau[x][y]]
     
        button = table[x][y]
        button.configure(bg=rgbtohex(r, g ,b))
        button.configure(text=str(tableau[x][y]))
        c = "BLACK"
     
        if r+g+b < 255 :
            c = "WHITE"
        button.configure(fg=c)
     
        if pos == (x, y):
            time.sleep(0.01)
            button.configure(bg=rgbtohex(235, 50, 10))
            root.update()
            time.sleep(0.01)
            button.configure(bg=rgbtohex(r, g ,b))
            root.update()
     
        root.update()
     
    def find_way(x, y):
        path = [(x, y)]
        while path[-1] != start:
            for X, Y in ((x-1, y),(x,y-1),(x,y+1),(x+1,y)):
                try:
                    if area[X][Y]==area[x][y]-1 and X >= 0 and Y >= 0 and area[X][Y]:            
                        path.append((X, Y))
                        x,y = X, Y
                        break
                except IndexError:
                    print("error",X,Y)
     
        if graph:
            for X, Y in path:
                button = table[X][Y]
                button.configure(bg=rgbtohex(185,45,255), fg="BLACK")
                time.sleep(0.02)
                root.update()
     
        for x, y in path:
            air[x][y] = 9
     
        with open("EXAMPLE FOR DEVELOPPEZ.NET_SOLVED.txt","w") as file:
            for line in air:
                file.write(str(line)[1:-1].replace(' ',''))
                file.write('\n')
     
        print('durée :',time.time()-st)
     
    def get_all_valide_cases(pos,pcd,k):
        x, y = pos
        poles = [(x-1, y),(x,y-1),(x,y+1),(x+1,y)]
     
        next_cases = []
        k+=1
        for X, Y in poles:
            if X < 0 and Y <0:
                continue
            if (X, Y) != pcd :
                try:
                    if area[X][Y]==1 or area[X][Y]>k:
                        if k < maxi:
                            next_cases.append([X, Y, k])
                except IndexError:
                    pass
     
     
        return next_cases
     
    def main():
        global maxi
        path_to_go = [(start[0], start[1], 1)]
        pcd = start
        while path_to_go:
            x, y, k = path_to_go.pop(0)
            next_cases = get_all_valide_cases((x, y), pcd, k)
            path_to_go.extend(next_cases)
            area[x][y]=k
            if (x,y) == end:
                if maxi > k:
                    maxi = k
            if graph:
                print_area(area,(x,y))
     
        find_way(end[0], end[1])
     
    def refresh_scrollbar(event):
        root.update()
     
    def launch(event):
        threading.Thread(target=main).start()
     
    def escape(event):
        if root.attributes('-fullscreen'):
            root.attributes('-fullscreen', False)
            root.geometry(f'{root.winfo_screenwidth()-10}x{root.winfo_screenheight()-90}+0+0')
        else:
            root.destroy()
     
    def colorize(button,x,y):
        r,g,b = colors[area[x][y]]
        bgcolor = rgbtohex(r,g,b)
        if area[x][y] == 1 :
            bgcolor = "WHITE"
        elif not area[x][y]:
            bgcolor = "GREY15"
     
        fgcolor = "BLACK"
        if not area[x][y]:
            fgcolor = "GREY50"
     
        button.configure(text=str(area[x][y]), bg=bgcolor, fg=fgcolor)
     
        with open("EXAMPLE FOR DEVELOPPEZ.NET_MODIFIED.txt","w") as file:
            for line in area:
                file.write(str(line)[1:-1].replace(' ',''))
                file.write('\n')
     
    def add(event):
        button = event.widget
        x, y = button.coords
        area[x][y]+=1
        colorize(button,x,y)
     
    def reduce(event):
        button = event.widget
        x, y = button.coords
        area[x][y]=max(0,area[x][y]-1)
        colorize(button,x,y)
     
    if graph:
        root = Tk()
        root.configure(bg="GREY15")
        root.attributes('-fullscreen', True)
        root.geometry(f'{root.winfo_screenwidth()}x{root.winfo_screenheight()}+0+0')
        vsb = Scrollbar(root, orient=VERTICAL)
        vsb.grid(row=0, column=1, sticky=N+S)
        vsb.bind('<Motion>',refresh_scrollbar)
        hsb = Scrollbar(root, orient=HORIZONTAL)
        hsb.grid(row=1, column=0, sticky=E+W)
        hsb.bind('<Motion>',refresh_scrollbar)
        c = Canvas(root,yscrollcommand=vsb.set, xscrollcommand=hsb.set,bg="GREY15")
        c.grid(row=0, column=0, sticky="news")
        vsb.config(command=c.yview)
        hsb.config(command=c.xview)
        root.grid_rowconfigure(0, weight=1)
        root.grid_columnconfigure(0, weight=1)
        fr = Frame(c,bg="GREY15")
        table = []
        for line in range(len(area)):
                ligne = []
                for col in range(len(area[0])):
                    bgcolor = "GREY15"
                    if area[line][col]:
                        bgcolor = "WHITE"
                    fgcolor = "BLACK"
                    if not area[line][col]:
                        fgcolor = "GREY50"
                    button = Button(fr, text=str(area[line][col]), borderwidth=1,  width = 3, height = 1, bg=bgcolor, fg=fgcolor)
                    button.grid(row=line, column=col)
                    button.coords = (line, col)
                    button.bind("<ButtonRelease-1>", add)
                    button.bind("<ButtonRelease-3>", reduce)
                    ligne.append(button)
                table.append(ligne)
        c.create_window(0, 0,  window=fr)    
        fr.update_idletasks()
        c.config(scrollregion=c.bbox("all"))
        c.xview_moveto(0.0)
        c.yview_moveto(0.0)
        root.update()
        root.bind('<Escape>', escape)
        root.bind('<Return>', launch)
        root.mainloop()
     
    else:
        main()


    Dernière version un peu brouillonne, je me suis perdue dans la logique du truc mais elle permet d'afficher tous les chemins minimums (quand plusieurs chemin font la même longueur et sont les plus courts) :
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    import sys, time, threading
    from tkinter import * 
     
    with open("test.txt","r") as fp :
        area = fp.read().replace(',','').splitlines()
     
    air = [[1 if int(x) else 0 for x in line] for line in area]
     
    print(time.ctime())
    st = time.time()
     
    #Mode graphique :
    graph = False
     
    #Exemple :
    '''air = [[0,1,0,0,0,0,0,0,0],
                [0,1,0,0,1,1,1,1,0],
                [0,1,0,1,1,0,0,1,0],
                [0,1,1,1,0,1,1,1,0],
                [0,1,0,0,0,1,0,1,0],
                [0,1,1,1,1,1,1,1,0],
                [0,1,0,1,0,0,0,1,0],
                [0,0,0,0,0,0,0,1,0]]'''
     
     
    area = [l.copy() for l in air]
    start = (0,1)
    end = (len(area)-1,len(area[-1])-2)
     
    if graph and len(area)*len(area[0])>10000:
        print("TOO BIG FOR GRAPHICAL MODE")
        graph = False
     
    def color(rgb=(255,45,45)):
        r,g,b = rgb
        degrades = [(r,g,b)]
     
        while r == 255 and g < 255:
            g+=1
            degrades.append((r,g,b))
        while g == 255 and r > 45:
            r-=1
            degrades.append((r,g,b))
        while g == 255 and b < 255:
            b+=1
            degrades.append((r,g,b))
        while b == 255 and g > 45:
            g-=1
            degrades.append((r,g,b))
     
        colors = [degrades[i] for i in range(0,len(degrades),int(len(degrades)/135))]
        sens = [i  for _ in range(50) for i in (-1,1)]
        colors = [color for i in sens for color in colors[::i]]
     
        return colors
     
    colors = color()
     
    def rgbtohex(r,g,b):
        return f'#{r:02x}{g:02x}{b:02x}'
     
     
    def print_area(tableau,pos):
        global sign
        x, y = pos
        r,g,b = colors[tableau[x][y]]
     
        button = table[x][y]
        button.configure(bg=rgbtohex(r, g ,b))
        button.configure(text=str(tableau[x][y]))
        c = "BLACK"
     
        if r+g+b < 255 :
            c = "WHITE"
        button.configure(fg=c)
     
        if pos == (x, y):
            #time.sleep(0.01)
            button.configure(bg=rgbtohex(235, 50, 10))
            root.update()
            #time.sleep(0.01)
            button.configure(bg=rgbtohex(r, g ,b))
            root.update()
     
        root.update()
     
    def find_way(x, y):
        path = [(x, y)]
        path_visited = [(x, y)]
        if graph:
            button = table[x][y]
            button.configure(bg=rgbtohex(185,45,255), fg="BLACK")
     
        while path:
            x,y = path.pop()
            for X, Y in ((x-1, y),(x,y-1),(x,y+1),(x+1,y)):
                if X >= 0 and Y >=0 and X < len(area[0]) and Y < len(area[1]):
                    if area[X][Y]==area[x][y]-1 and area[X][Y]:
                        if (X,Y) not in path_visited:
                            path.append((X,Y))
                            path_visited.append((X,Y))
                            if graph:
                                button = table[X][Y]
                                button.configure(bg=rgbtohex(185,45,255), fg="BLACK")
                                root.update()
     
        for x, y in path_visited:
            air[x][y] = 9
     
        with open("TEST_SOLVED.txt","w") as file:
            for line in air:
                file.write(str(line)[1:-1].replace(' ',''))
                file.write('\n')
     
        print('durée :',time.time()-st)
     
    def get_all_valide_cases(pos, pcds, k):
        x, y = pos
        poles = [(x-1, y),(x,y-1),(x,y+1),(x+1,y)]
        next_cases = []
        k+=1
        for X, Y in poles:
            if X < 0 and Y <0:
                continue
            if (X, Y) not in pcds:
                try:
                    if area[X][Y]==1 or area[X][Y]>k:
                        next_cases.append((X, Y, k))
                        pcds.append((X, Y))
                except IndexError:
                    pass
     
     
        return next_cases, pcds
     
    def main():
        path_to_go = [(start[0], start[1], 1)]
        pcds = [start]
        #pcd = start
        while path_to_go:
            x, y, k = path_to_go.pop(0)
            #print(x,y,k)
            next_cases, pcds = get_all_valide_cases((x, y), pcds, k)
            path_to_go.extend(next_cases)
            area[x][y]=k        
            if graph:
                print_area(area,(x,y))
     
        print('END')
        find_way(end[0], end[1])
     
    def refresh_scrollbar(event):
        root.update()
     
    def launch(event):
        threading.Thread(target=main).start()
     
    def escape(event):
        if root.attributes('-fullscreen'):
            root.attributes('-fullscreen', False)
            root.geometry(f'{root.winfo_screenwidth()-10}x{root.winfo_screenheight()-90}+0+0')
        else:
            root.destroy()
     
    def colorize(button,x,y):
        r,g,b = colors[area[x][y]]
        bgcolor = rgbtohex(r,g,b)
        if area[x][y] == 1 :
            bgcolor = "WHITE"
        elif not area[x][y]:
            bgcolor = "GREY15"
     
        fgcolor = "BLACK"
        if not area[x][y]:
            fgcolor = "GREY50"
     
        button.configure(text=str(area[x][y]), bg=bgcolor, fg=fgcolor)
     
        with open("EXAMPLE FOR DEVELOPPEZ.NET_MODIFIED.txt","w") as file:
            for line in area:
                file.write(str(line)[1:-1].replace(' ',''))
                file.write('\n')
     
    def add(event):
        button = event.widget
        x, y = button.coords
        area[x][y]+=1
        colorize(button,x,y)
     
    def reduce(event):
        button = event.widget
        x, y = button.coords
        area[x][y]=max(0,area[x][y]-1)
        colorize(button,x,y)
     
    if graph:
        root = Tk()
        root.configure(bg="GREY15")
        root.attributes('-fullscreen', True)
        root.geometry(f'{root.winfo_screenwidth()}x{root.winfo_screenheight()}+0+0')
        vsb = Scrollbar(root, orient=VERTICAL)
        vsb.grid(row=0, column=1, sticky=N+S)
        vsb.bind('<Motion>',refresh_scrollbar)
        hsb = Scrollbar(root, orient=HORIZONTAL)
        hsb.grid(row=1, column=0, sticky=E+W)
        hsb.bind('<Motion>',refresh_scrollbar)
        c = Canvas(root,yscrollcommand=vsb.set, xscrollcommand=hsb.set,bg="GREY15")
        c.grid(row=0, column=0, sticky="news")
        vsb.config(command=c.yview)
        hsb.config(command=c.xview)
        root.grid_rowconfigure(0, weight=1)
        root.grid_columnconfigure(0, weight=1)
        fr = Frame(c,bg="GREY15")
        table = []
        for line in range(len(area)):
                ligne = []
                for col in range(len(area[0])):
                    bgcolor = "GREY15"
                    if area[line][col]:
                        bgcolor = "WHITE"
                    fgcolor = "BLACK"
                    if not area[line][col]:
                        fgcolor = "GREY50"
                    button = Button(fr, text=str(area[line][col]), borderwidth=1,  width = 3, height = 1, bg=bgcolor, fg=fgcolor)
                    button.grid(row=line, column=col)
                    button.coords = (line, col)
                    button.bind("<ButtonRelease-1>", add)
                    button.bind("<ButtonRelease-3>", reduce)
                    ligne.append(button)
                table.append(ligne)
        c.create_window(0, 0,  window=fr)    
        fr.update_idletasks()
        c.config(scrollregion=c.bbox("all"))
        c.xview_moveto(0.0)
        c.yview_moveto(0.0)
        root.update()
        root.bind('<Escape>', escape)
        root.bind('<Return>', launch)
        root.mainloop()
     
    else:
        main()

    Le faite d'avoir utilisé pop(0) a tout changé ! Plus de repassages intempestifs sur les boucles... Par contre j'ai du bidouiller un truc avec les listes pour l'empêcher de tester plusieurs fois les mêmes positions (pas compris... plus ça avançait plus il radotait).

    Dernière modification par Invité ; 07/01/2022 à 03h00.

  14. #34
    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
    Citation Envoyé par LeNarvalo Voir le message
    Je reviens sur un truc :
    with open("EXAMPLE FOR DEVELOPPEZ.NET.txt","r") as fp :.
    C'est vraiment important pour le mode lecture ?
    Pour le mode écriture je savais mais je pensais que pour le mode lecture on ne risquait pas grand chose à utiliser file = open('...', 'r')
    En fait j'ai déjà eu des cas de figure, où ce que l'on fait entre le open et le close produit une erreur. Et dans ce cas, si vous coder avec un IDE, la console python reste en cours d'exécution et donc votre descripteur de fichier reste ainsi accroché à ce script. Si vous relancez le script, alors vous avez des erreurs du type "je peux pas accéder au fichier", car cela fait des accès concurrentiels. Et ca que ce soit en lecture ou en écriture. Si vous essayez de supprimer le fichier via votre explorateur de fichier windows, là pareil, vous ne pourrez pas, on vous dira que le fichier est utilisé. Seul moyen : redémarrer votre IDE. Un peu pénible donc. Avec le with, je n'ai jamais eu de souci : meme avec une erreur à l'intérieur du bloc, le fichier se ferme bien.

    Vous qui regardez les perfs, au passage cette amélioration syntaxique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for X, Y in ((x-1, y),(x,y-1),(x,y+1),(x+1,y)):
    doit aussi être plus rapide que votre ancienne version, car on ne créé pas des itérateurs, pour tester certaines conditions pour voir si on prend le couple (i,j) ou non, là on construit directement les tuples dont on a besoin, sans condition ni structure annexe.

    Pour le import *, moi même je ne connais pas très bien tkinter. Si je récupère votre code, que je le lis et que je vois un appel à une fonction (genre table par exemple), alors au premier coup d'oeil je ne sais pas si c'est une fonction que vous vous avez défini plus haut, où si elle vient d'ailleurs ... Ca peut paraitre anodin, mais pour la lisibilité du code c'est également capital. Donc en plus de l'argument que le import * peut amené à des conflits, ca fait 2 bonnes raisons de s'y mettre dès maintenant (c'est une habitude à prendre).

    Pour les tests il n'y a pas forcément besoin d'aller chercher très loin. Vous pouvez par exemple à la fin de votre code écrire le path dans un fichier (ca peut etre en .json par exemple si vous voulez pas vous embêtez à gérer un reader/writer de path). Vous faites tournez le code 1 fois pour toute avec ca, et ca vous produit donc un fichier avec le path solution de référence, fichier que vous n'allez plus jamais toucher. Ensuite vous remodifiez le code, pour ne pas écrire le .json, mais cette fois ci pour le lire, et vous comparez si son contenu est égal au path que vous venez de calculer.

    Ca donne qqch comme ca :
    Pour écrire la solution de référence une bonne fois pour toute :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import json
    with open('le_nom_de_mon_cas_test_soluce.json', 'w') as fp :
        json.dump(fp, path)
    Pour tester à chaque fois que ce que vous calculez est bien conforme à la solution attendue de référence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    with open('le_nom_de_mon_cas_test_soluce.json', 'r') as fp :
        ref_path = json.load(fp)
    ref_path = list(map(tuple, ref_path))
    assert(path==ref_path)
    avec le petit assert qui vous explose tout de suite à la figure si path est différent de ref_path.
    Notez ici le map(tuple,...), car en json on ne stocke que des listes. Le path étant une liste de tuples, il est stocké dans le json comme une liste de liste. Il faut donc repasser de liste à tuple avant de pouvoir faire la comparaison, à moins sinon de se farcir une comparaison plus manuelle en itérant sur les éléments pour les comparer un à un.
    J'ai fais le choix du json ici, qui est un grand classique en python, mais tout autre format convient aussi.

    Notez également que quand le code sera factorisé (tout dans des fonctions, sans plus aucun mot global), alors vous pourrez avoir non plus 1 fichier d'input, et 1 fichier de la solution de référence, mais N fichier d'input, avec leur solution de référence correspondante. Et vous pourrez faire une boucle sur vos N cas tests, et tous les testez. Car vous n'êtes pas à l'abri qu'une modif de votre code, qui n'impacte pas la résolution du labyrinthe que vous regardez impacte la résolution d'un autre labyrinthe ! En faisant plusieurs tests on élimine pas cette problématique, mais on la réduit fortement. Même remarque aussi sur la mesure de la performance. La performance est très dépendante du labyrinthe choisi. Ainsi vous pourriez comparer les performances en fonctions du labyrinthe test choisi. Certains choix algorithmique, qui peuvent vous paraitre améliorer le temps d'exécution, peut en fait le dégradé pour d'autre labyrinthe. Surtout pour des labyrinthes un peu "extrêmes", avec soit beaucoup d'embranchement mais des très court, ou alors peu d'embranchement mais avec des chemins très long, ou encore, des labyrinthes bourrés de cycles (et là encore il y a des différence entre des petits cycles et des grands cycles), là variabilité là entre ces cas peut être assez ahurissante sur les temps d'exe.

    Donc ca me parait être le bon moment pour vous d'étoffer vos tests et de factoriser votre code pour pouvoir les faire tourner facilement, car faire des tests de perf sur un seul et unique labyrinthe ce ne veut pas forcément dire grand chose et ce n'est pas vraiment pertinent...

  15. #35
    Invité
    Invité(e)
    Par défaut
    Merci pour ces précieux conseils @lg_53 !

    Tu remarqueras que j'ai essayé de prendre acte de certaines remarques, par contre je vais avoir beaucoup de mal à utiliser tk.Label au lieu de Label, ça fait 10 ans que je fais mes scripts ainsi...

    J'utilise un script pour créer des labyrinthes que je modifie soit à l'aide de l'interface visuelle TKinter (les boutons sont interactifs) soit à la main, j'ai quelques tests à mon actif ! Ce script n'est qu'un bout de mon projet, il n'aura pas vocation à tester beaucoup plus d'un labyrinthe (vu le temps que j'ai mis à le faire).

    Est-ce si grave de ne pas utiliser systématiquement les arguments mais des variables globales ? Je n'utilise presque plus global dans ma dernière version (cf. plus bas) mais je trouve ça un peu con de passer mon tableau dans une fonction alors qu'il est global puisque créé au début du script.

    Je suis fier et heureux de vous présenter ma dernière mouture, ultra efficace !!!
    Moins de 15 secondes pour résoudre mon énorme labyrinthe et trouver tous les plus courts chemins !
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    import sys, time, threading
    from tkinter import * 
     
    with open("test.txt","r") as fp :
        area = fp.read().replace(',','').splitlines()
     
    air = [[1 if int(x) else 0 for x in line] for line in area]
     
    print(time.ctime())
    st = time.time()
     
    #Mode graphique :
    graph = False
     
    #Exemple :
    '''air = [[0,1,0,0,0,0,0,0,0],
                [0,1,0,0,1,1,1,1,0],
                [0,1,0,1,1,0,0,1,0],
                [0,1,1,1,0,1,1,1,0],
                [0,1,0,0,0,1,0,1,0],
                [0,1,1,1,1,1,1,1,0],
                [0,1,0,1,0,0,0,1,0],
                [0,0,0,0,0,0,0,1,0]]'''
     
     
    area = [l.copy() for l in air]
    start = (0,1)
    end = (len(area)-1,len(area[-1])-2)
     
    if graph and len(area)*len(area[0])>10000:
        print("TOO BIG FOR GRAPHICAL MODE")
        graph = False
     
    def color(rgb=(255,45,45)):
        r,g,b = rgb
        degrades = [(r,g,b)]
     
        while r == 255 and g < 255:
            g+=1
            degrades.append((r,g,b))
        while g == 255 and r > 45:
            r-=1
            degrades.append((r,g,b))
        while g == 255 and b < 255:
            b+=1
            degrades.append((r,g,b))
        while b == 255 and g > 45:
            g-=1
            degrades.append((r,g,b))
     
        colors = [degrades[i] for i in range(0,len(degrades),max(100,int(len(degrades)/(len(area)*2))))]
        sens = [i  for _ in range(50) for i in (-1,1)]
        colors = [color for i in sens for color in colors[::i]]
     
        return colors
     
    if graph:
        colors = color()
     
    def rgbtohex(r,g,b):
        return f'#{r:02x}{g:02x}{b:02x}'
     
     
    def print_area(tableau,pos):
        x, y = pos
        r,g,b = colors[tableau[x][y]]
     
        button = table[x][y]
        button.configure(bg=rgbtohex(r, g ,b))
        button.configure(text=str(tableau[x][y]))
        c = "BLACK"
     
        if r+g+b < 255 :
            c = "WHITE"
        button.configure(fg=c)
     
        if pos == (x, y):
            #time.sleep(0.01)
            button.configure(bg=rgbtohex(235, 50, 10))
            root.update()
            #time.sleep(0.01)
            button.configure(bg=rgbtohex(r, g ,b))
            root.update()
     
        root.update()
     
    def find_way(x, y):
        path = [(x, y)]
        path_visited = [(x, y)]
        if graph:
            button = table[x][y]
            button.configure(bg=rgbtohex(185,45,255), fg="BLACK")
     
        while path:
            x,y = path.pop()
            for X, Y in ((x-1, y),(x,y-1),(x,y+1),(x+1,y)):
                if X >= 0 and Y >=0 and Y < len(area[0]) and X < len(area):
                    if area[X][Y]==area[x][y]-1 and area[X][Y]:
                        if (X,Y) not in path_visited:
                            path.append((X,Y))
                            path_visited.append((X,Y))
                            if graph:
                                button = table[X][Y]
                                button.configure(bg=rgbtohex(185,45,255), fg="BLACK")
                                #time.sleep(0.05)
                                root.update()
     
        for x, y in path_visited:
            air[x][y] = 9
     
        with open("test_solved.txt","w") as file:
            for line in air:
                file.write(str(line)[1:-1].replace(' ',''))
                file.write('\n')
     
        print('Finish at ',time.ctime())
        print('Durée :',time.time()-st)
     
    def get_all_valide_cases(pos, pcds, k):
        x, y = pos
        poles = [(x-1, y),(x,y-1),(x,y+1),(x+1,y)]
        next_cases = []
     
        k+=1
        for X, Y in poles:
            if X < 0 or Y <0:
                continue
            if (X, Y) not in pcds:
                try:
                    if area[X][Y]==1 or area[X][Y]>k:
                        next_cases.append((X, Y, k))
                        pcds.append((X, Y))
                except IndexError:
                    pass
     
        return next_cases, pcds
     
    def main():
        path_to_go = [(start[0], start[1], 1)]
        pcds = [start,start]
        while path_to_go:
            x, y, k = path_to_go.pop(0)
            #print(x,y,k)
            next_cases, pcds = get_all_valide_cases((x, y), pcds, k)
            pcds.pop(0)
            path_to_go.extend(next_cases)
            area[x][y]=k        
            if graph:
                print_area(area,(x,y))
     
        #print('END',time.time()-st) #,'\nLENGTH PCDS:',len(pcds))
        find_way(end[0], end[1])
     
    def refresh_scrollbar(event):
        root.update()
     
    def launch(event):
        global st
        st = time.time()
        threading.Thread(target=main).start()
     
    def escape(event):
        if root.attributes('-fullscreen'):
            root.attributes('-fullscreen', False)
            root.geometry(f'{root.winfo_screenwidth()-10}x{root.winfo_screenheight()-90}+0+0')
        else:
            root.destroy()
     
    def colorize(button,x,y):
        r,g,b = colors[area[x][y]]
        bgcolor = rgbtohex(r,g,b)
        if area[x][y] == 1 :
            bgcolor = "WHITE"
        elif not area[x][y]:
            bgcolor = "GREY15"
     
        fgcolor = "BLACK"
        if not area[x][y]:
            fgcolor = "GREY50"
     
        button.configure(text=str(area[x][y]), bg=bgcolor, fg=fgcolor)
     
        with open("EXAMPLE FOR DEVELOPPEZ.NET_MODIFIED.txt","w") as file:
            for line in area:
                file.write(str(line)[1:-1].replace(' ',''))
                file.write('\n')
     
    def add(event):
        button = event.widget
        x, y = button.coords
        area[x][y]+=1
        colorize(button,x,y)
     
    def reduce(event):
        button = event.widget
        x, y = button.coords
        area[x][y]=max(0,area[x][y]-1)
        colorize(button,x,y)
     
    if graph:
        root = Tk()
        root.configure(bg="GREY15")
        root.attributes('-fullscreen', True)
        root.geometry(f'{root.winfo_screenwidth()}x{root.winfo_screenheight()}+0+0')
        vsb = Scrollbar(root, orient=VERTICAL)
        vsb.grid(row=0, column=1, sticky=N+S)
        vsb.bind('<Motion>',refresh_scrollbar)
        hsb = Scrollbar(root, orient=HORIZONTAL)
        hsb.grid(row=1, column=0, sticky=E+W)
        hsb.bind('<Motion>',refresh_scrollbar)
        c = Canvas(root,yscrollcommand=vsb.set, xscrollcommand=hsb.set,bg="GREY15")
        c.grid(row=0, column=0, sticky="news")
        vsb.config(command=c.yview)
        hsb.config(command=c.xview)
        root.grid_rowconfigure(0, weight=1)
        root.grid_columnconfigure(0, weight=1)
        fr = Frame(c,bg="GREY15")
        table = []
        for line in range(len(area)):
                ligne = []
                for col in range(len(area[0])):
                    bgcolor = "GREY15"
                    if area[line][col]:
                        bgcolor = "WHITE"
                    fgcolor = "BLACK"
                    if not area[line][col]:
                        fgcolor = "GREY50"
                    button = Button(fr, text=str(area[line][col]), borderwidth=1,  width = 3, height = 1, bg=bgcolor, fg=fgcolor)
                    button.grid(row=line, column=col)
                    button.coords = (line, col)
                    button.bind("<ButtonRelease-1>", add)
                    button.bind("<ButtonRelease-3>", reduce)
                    ligne.append(button)
                table.append(ligne)
        c.create_window(0, 0,  window=fr)    
        fr.update_idletasks()
        c.config(scrollregion=c.bbox("all"))
        c.xview_moveto(0.0)
        c.yview_moveto(0.0)
        root.update()
        root.bind('<Escape>', escape)
        root.bind('<Return>', launch)
        root.mainloop()
     
    else:
        main()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Fri Jan  7 18:55:09 2022
    Finish at  Fri Jan  7 18:55:24 2022
    Durée : 14.332780599594116
    >>>
    Cependant, des questions persistent dans ma petite tête :
    - Est-ce intéressant d'avoir séparer le code entre la fonction main() (ligne 138) et get_all_valide_cases() (ligne 119) ou à l'inverse est-ce que ça nuit à la lisibilité ?

    - Ligne 128 je regarde dans la liste pcds avec if (X, Y) not in pcds: et ligne 145 j'utilise pop(0) (qui semble plus efficace que liste = liste[1:]), comment faire mieux sachant que le script se comporte comme dans la vidéo, càd qu'il saute d'un chemin à l'autre lors de la recherche. L'idéal serait de faire if (X, Y) != pcds[index] (encore faut-il connaître cet index) ou est-ce négligeable à première vue ?

    Merci pour votre participation active les anciens !

  16. #36
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 817
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Est-ce si grave de ne pas utiliser systématiquement les arguments mais des variables globales ? Je n'utilise presque plus global dans ma dernière version (cf. plus bas) mais je trouve ça un peu con de passer mon tableau dans une fonction alors qu'il est global puisque créé au début du script.
    Déjà si tu mets tout ton script en fonctions, tu n'as plus de globales. Ensuite l'instruction global n'a pas pour but de déclarer une variable globale mais d'informer le moteur Python que tu comptes modifier cette globale dans ta fonction. Pour simplifier une variable globale est toujours implicitement utilisable en lecture mais n'est modifiable que si tu le spécifies explicitement.
    Le souci originel des globales dans les langages comme C/C++ vient au départ du fait que les globales sont modifiables sans contrainte. Ce qui pose alors souci lorsqu'une globale est modifiée accidentellement car il est alors difficile de trouver l'origine. Il existe pourtant une technique pour "aider" la recherche: redéclarer la globale via "extern"
    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int glob;
     
    void toto() {
    	extern int glob;		// Indique que la fonction accèdera à la globale "glob"
    	...
    }
    Ainsi on peut plus facilement identifier les fonctions qui accèdent à "glob". Technique pourtant peu utilisée (peut-être parce que peu connue).

    Un second souci des globales de ces langages c'est que si tu définis par accident une variable locale de même nom, le compilateur ne dit rien mais tu perds l'accès à la globale ce qui est source de bug potentiel.

    Python a éliminé ces deux soucis. Le premier en forçant l'utilisation de l'instruction global pour indiquer l'intention de modification ; et refuse la création d'une variable de même nom dans une fonction si la globale a été utilisée même en simple lecture (en fait si on le fait on retombe dans une syntaxe de modification d'une globale sans l'avoir spécifié via global).
    Donc en Python utiliser des globales ça devient moins grave. Sauf sur un point incontournable: l'indépendance des fonctions. Dans la théorie des langages, une fonction est un objet totalement indépendant. Il reçoit en entrée les éléments dont il a besoin, fait son travail en interne et renvoie un résutat (et pour l'extrémiste échevelé aux yeux fous, ne peut le retourner qu'à la fin => interdit donc les return sauvages en plein milieu du code). Cela permet de réutiliser la fonction dans différents contextes, la parallélisation des tâches sans risque de collision, rend le code moins opaque pour celui qui le lit et plus facilement évolutif. Généralement il n'y a rien qui justifie vraiment l'utilisation de globales (rien que la flemme de travailler et découper proprement son algo en tâches élémentaires). Bref les globales n'apportent rien et génèrent un risque possible, autant s'en passer. Comme l'a dit wiztrics, "les bons risques sont ceux qu'on ne prend pas" (j'ai adoré cette phrase).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  17. #37
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 198
    Par défaut
    hello,
    LeNarvalo il a l'air de fonctionner plutôt bien ton script, mais j'ai quelques soucis dans le mode graphique avec de grands labyrinthes.

    1 - Tu as fait une limitation à 100x100 pour les labyrinthes en mode graphique. Chez moi quand je mets en entrée un labyrinthe de 100x100 en entrée cela coince pas d'affichage pas de message d'erreur. Par contre avec un labyrinthe de 99x99 cela passe.
    2 - Ta table des couleurs fait apparemment 900 éléments ce qui qui provoquent une erreur d'index pour les labyrinthes assez grands en mode graphique ( > 70x70)
    3 - l'affichage des chiffres en 3 digits dans les cases passent tout juste (diminuer la taille de la police ?)

    Ami calmant, J.P

  18. #38
    Invité
    Invité(e)
    Par défaut
    Salut Jurassic Pork !

    1. J'ai mis 100x100 sans même vérifier ^^', je vais mettre 99x99 du coup.

    2. Pareil, j'ai pas fait assez de tests de mon côté en mode graphique.
    A modifier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    colors = [degrades[i] for i in range(0,len(degrades),max(5,int(len(degrades)/(len(area)*2))))]
    sens = [i  for _ in range(100) for i in (-1,1)]
    colors = [color for i in sens for color in colors[::i]
    Sinon, je ne sais pas si tu avais lu ce sujet que j'avais créé il y a un an presque jour pour jour : https://www.developpez.net/forums/d2...ir-liste-yoyo/

    3. J'ai rajouté quelques lignes pour créer une police dynamique, mais pas simple vu que le bouton est de base dimensionné en fonction de la taille de la police... J'ai utilisé une image virtuelle sur le bouton pour pouvoir définir une taille en pixel du bouton plutôt qu'un facteur fonction de la taille de la police !
    Lorsque j'utilise un labyrinthe de 75x75 avec mes modifs et que je bouge trop les scrollbars de la fenêtre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Exception in Tkinter callback
    Traceback (most recent call last):
      File "C:\Python39\lib\tkinter\__init__.py", line 1891, in __call__
        args = self.subst(*args)
      File "C:\Python39\lib\tkinter\__init__.py", line 1577, in _substitute
        e.num = getint_event(b)
      File "C:\Python39\lib\tkinter\__init__.py", line 1556, in getint_event
        return getint(s)
    RecursionError: maximum recursion depth exceeded while calling a Python object
    Tkinter ne serait pas fait pour ça ?



    Dernière version, encore plus rapide (7.5 sec au lieu de 15)
    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
    def get_all_valide_cases(pos, added, k):
        x, y = pos
        poles = [(x-1, y),(x,y-1),(x,y+1),(x+1,y)]
        next_cases = []
     
        k+=1
        for X, Y in poles:
            if X < 0 or Y <0:
                continue
            if (X, Y) not in added:
                try:
                    if area[X][Y]==1 or area[X][Y]>k:
                        next_cases.append((X, Y, k))
                        added.append((X, Y))
                except IndexError:
                    pass
     
        return next_cases, added
     
    def main():
        path_to_go = [(start[0], start[1], 1)]
        added = [start,start]
     
        while path_to_go:
            x, y, k = path_to_go.pop(0)
     
            next_cases, added = get_all_valide_cases((x, y), added, k)
     
            for _ in next_cases:
                added.pop(0)
     
            path_to_go.extend(next_cases)
     
            area[x][y]=k
     
            if graph:
                print_area(area,(x,y))
     
        find_way(end[0], end[1])
    Me demandez pas comment ça marche...
    Dernière modification par Invité ; 08/01/2022 à 16h42.

  19. #39
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 198
    Par défaut
    voilà ce que cela donne en changeant la taille de la police :

    avec une taille 5 :

    Nom : mazeFont5.PNG
Affichages : 115
Taille : 38,2 Ko

    avec une taille 6 :

    Nom : mazeFont6.PNG
Affichages : 116
Taille : 22,4 Ko

    avec le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    myFont = font.Font(size=6)
    // .....
    button['font'] = myFont

  20. #40
    Invité
    Invité(e)
    Par défaut
    Pour garder la taille des boutons :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pixelVirtual = PhotoImage(width=1, height=1)
    button = Button(fr, text="blabla", borderwidth=1, width=20, height=20, image=pixelVirtual, font=("Arial",10), compound="c")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    num = 1234
    size = 10
    if len(num)>1:
         size -= len(num)
    button.configure(text=num, font=("Arial",size))
    Nom : examplepng.png
Affichages : 117
Taille : 2,5 Ko
    Dernière modification par Invité ; 08/01/2022 à 22h53.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. Réponses: 5
    Dernier message: 19/08/2019, 17h45
  2. error message sur un script
    Par miroufsn dans le forum Langage
    Réponses: 2
    Dernier message: 18/12/2007, 08h14
  3. Script error sur envoi de formulaire sous IE
    Par loick2000 dans le forum Général JavaScript
    Réponses: 20
    Dernier message: 14/05/2007, 17h30
  4. Question sur un script
    Par Gnux dans le forum Linux
    Réponses: 8
    Dernier message: 07/07/2005, 17h03
  5. installation sur serveur + script
    Par liliprog dans le forum Langages de programmation
    Réponses: 7
    Dernier message: 18/08/2004, 15h18

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