Bibm@th

Forum de mathématiques - Bibm@th.net

Bienvenue dans les forums du site BibM@th, des forums où on dit Bonjour (Bonsoir), Merci, S'il vous plaît...

Vous n'êtes pas identifié(e).

#1 22-04-2011 15:32:56

totomm
Invité

[VBasic puis Python] Pour l'enigme "Vases communicants" de freddy

Bonjour,

@yoshi : ci-dessous en VBasic 2008 express

Module Urnes

    'Valeurs globales pour la procédure Répartir3N
    Private Nmaxi As Integer = 10
    Dim Urnes(2) As Integer
    Dim De(Nmaxi), Vers(Nmaxi) As Integer 'Mémoire du niveau p
    Dim wL As New System.IO.StringWriter 'wL reçoit les lignes à écrire dans RTB
    Dim nbSolutions As Integer = 0

    Sub Répartir3N(ByRef RTB As RichTextBox) 'RTB reçoit les résultats

        wL.WriteLine("Début de calcul")
        For NN As Integer = Nmaxi To Nmaxi
            Urnes(0) = 3 * NN : Urnes(1) = 0 : Urnes(2) = 0
            De(0) = 0 : Vers(0) = 0
            NiveauP(NN, 1) 'récursions
        Next
        wL.WriteLine("Fin de Calcul")
        RTB.Text = wL.ToString
        wL.Close()
    End Sub 'Répartir3N

    Sub NiveauP(ByVal NN As Integer, ByVal NP As Integer)
        For X As Integer = 0 To 2
            For Y As Integer = 0 To 2
                If X <> Y AndAlso Urnes(X) >= NP Then
                    De(NP) = X : Vers(NP) = Y
                    Urnes(X) -= NP : Urnes(Y) += NP 'transfert
                    If NP = NN AndAlso Urnes(0) = NN AndAlso Urnes(1) = NN AndAlso Urnes(2) = NN Then
                        'Si l'on ne veut que les solutions en n étapes,
                        'ajouter "NP = NN AndAlso " entre if et Urnes(0)
                        nbSolutions += 1 'Visualiser un résultat
                        wL.WriteLine("Solution N° " & nbSolutions)
                        wLignes(NN)
                    End If
                    If NP < NN Then NiveauP(NN, NP + 1)
                    Urnes(X) += NP : Urnes(Y) -= NP 'annuler transfert
                End If
            Next
        Next
    End Sub 'NiveauP

    Sub wLignes(ByVal NN As Integer)
        Dim U(2) As Integer
        U(0) = 3 * NN : U(1) = 0 : U(2) = 0
        For ii = 0 To NN
            U(De(ii)) -= ii
            U(Vers(ii)) += ii
            Dim Texte As String = "n=" & NN & vbTab & " p=" & ii _
            & vbTab & " de " & De(ii) _
            & " vers " & Vers(ii) _
            & vbTab & " en 0: " & U(0) _
            & vbTab & " en 1: " & U(1) _
            & vbTab & " en 2: " & U(2)
            wL.WriteLine(Texte)
        Next
    End Sub 'wLignes

End Module

#2 22-04-2011 16:16:54

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [VBasic puis Python] Pour l'enigme "Vases communicants" de freddy

Re,

Merci, je vais étudier ça...
Je ne pensais pas que VB était aussi verbeux : ça ne va pas être de la tarte...
Donc tu as un "Module Urnes" et les Sub sont des procédures, des sous-prog dans les Basic que je connais, on y rentrais par Sub(paramètres), voire Gosub et alors il y avait un Return à la fin.
Comment on rentre dans ton prog ? Ou plus exactement, tu lui passes la valeur de nn où ? Comment ?
Tu appelles Sub wLignes(5) par exemple ?
Autant de personnes, autant d'habitudes de programmations..
Moi je veux faire :

def machin(paramètres):


    return (valeurs)

def truc(paramètres):

    appel de machin(paramètres)

     return(valeurs)

# prog principal
Entrée demandée du paramètre n ou  directement n = ...
Initialisation des états des urnes
valeurs = machin(paramètres)
print valeurs

Je ne sais pas si je vais arriver déjà à réaliser un organigramme détaillé de ce que te fais ton prog.
Je vais essayer mais j'en doute...
Pourtant, en Turbo Basic, j'avais écrit un programme de calculs astrologiques complet, un programme de calcul des éclipses de lune à venir transcrits du Basic Amstrad CPC 6128 en GFA BAsic (pour Atari) puis en Turbo Basic, de même qu'un prog de calculs financiers que j'ai depuis retraduit en Python, du Basic Amstad, vers Turbo Basic puis Python mes prog de calculs de carrés magiques : donc j'ai quand même une certaine expérience en la matière, mais l'âge aidant, on se rouille...

Je vais essayer. Je ne rendrai les armes qu'en dernier recours...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#3 23-04-2011 12:44:55

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [VBasic puis Python] Pour l'enigme "Vases communicants" de freddy

Re,

Je commence à démêler l'écheveau...
Je présume que la ligne VB :
          For NN As Integer = Nmaxi To Nmaxi
deviendra en Python :
          for nn in range(nmaxi,nmaxi+1)
pour qu'il y ait au moins une itération...
Mais pour l'instant je n'ai pas pigé pourquoi nn=nmaxi ne suffirait puisque la boucle est inutile s'il n'y a qu'un tour...
Ou alors, c'est que VB se comporte de façon radicalement différente avec les boucles ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#4 23-04-2011 20:34:14

totomm
Invité

Re : [VBasic puis Python] Pour l'enigme "Vases communicants" de freddy

Bonjour,

C'est après quelques essais, pour n'avoir qu'un seul gros résultat sur Nmaxi assez grand (temps de calcul !)
il y avait avant : For NN As Integer = 5 To Nmaxi

Cordialement

#5 23-04-2011 20:57:39

totomm
Invité

Re : [VBasic puis Python] Pour l'enigme "Vases communicants" de freddy

Bonjour,

Le VBasic de nos jours est un langage avec tous (ou presque) les atouts du C# ou du C++ : Même langage intermédiaire
Soit on choisit une "application console", mais  il faut agir comme avec l'ancien DOS
soit on choisit une application "Windows", c'est-à dire avec une fenêtre et des possibilités de menus, barres d'outils, etc....C'est ce que je fais, mais je remplis la fenêtre avec un "contrôle" TextBox dans lequel je visualise mes résultats.
VBasic est verbeux si on choisit un Typage fort : on y gagne en débogage du programme...
Pour lancer mon programme, le point d'entrée est choisi dans les proriétés de projet et j'y mets un premier appel à ma première procédure

Il n'y a plus depuis longtemps de goto dans les programmes structurés.
les return sont utilisés dans les fonctions et non dans les sub (c'est leur différence)

On se rouille effectivement très vite, car les syntaxes sont trop différentes.
Je me suis mis un peeu à Python qui est très concis, mais j'ai trop d'habitudes avec les langages du Visual Studio.

Cordialement

#6 24-04-2011 19:21:29

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [VBasic puis Python] Pour l'enigme "Vases communicants" de freddy

Salut,

Python aussi t'offre la possibilité d'utiliser un environnement graphique : un est livré en standard : Tkinter, d'autres sont téléchargeables : WxPython, PyQt... etc.

Bon, ça y est, j'ai transcrit ton truc.
Mais j'ai un problème d'affichage un peu "farfelu"...
Pour nmaxi=7, j'ai bien Urne A = 7, Urne B = 7, Urne C = 7.
Quand je passe à l'affichage, voilà ce que donne :

   ---> Solution n° 1 <---
p = 0 de  A vers  A        * en A : 21  * en B :  0  * en C :  0  *
p = 1 de  A vers  B        * en A : 20  * en B :  1  * en C :  0  *
p = 2 de  A vers  B        * en A : 18  * en B :  3  * en C :  0  *
p = 3 de  A vers  B        * en A : 15  * en B :  6  * en C :  0  *
p = 4 de  A vers  B        * en A : 11  * en B : 10  * en C :  0  *
p = 5 de  A vers  B        * en A :  6  * en B : 15  * en C :  0  *
p = 6 de  A vers  B        * en A :  0  * en B : 21  * en C :  0  *
p = 7 de  B vers  C        * en A :  0  * en B : 14  * en C :  7  *

Mes tableaux De et Vers sont faux...
J'ai reconstitué les bons à la main, reste à trouver ce qui cloche dans la fonction niveaup0
Ce ne sera pas pour ce soir : j'en ai assez !

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#7 25-04-2011 08:53:34

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [VBasic puis Python] Pour l'enigme "Vases communicants" de freddy

Re,

C'est bon, j'ai corrigé, mais je vais encore réfléchir, parce que pour gérer le compteur de solutions, j'ai dû utiliser une variable globale (c'est le mal !) sinon, à chaque appel de fonction il repartait à zéro ! Pas satisfaisant.

# usr/bin/env python
# -*- coding: Latin-1 -*-

## Version 1 ##

def niveaup(nn,np,Urne,De,Vers):
    global sol
    for x in xrange(3):
        for y in xrange(3):
            if x!=y and Urne[x]>=np:
                De[np],Vers[np]=x,y
                Urne[x]-=np
                Urne[y]+=np
                if np==nn and Urne==[nn,nn,nn]:
                    sol+=1
                    print "   ---> Solution n°",sol,"<---"
                    Affiche_resultats(nn,De,Vers)
                if np<nn:
                    niveaup(nn,np+1,Urne,De,Vers)
                Urne[x]+=np
                Urne[y]-=np
    return

def Affiche_resultats(nn,De,Vers):
    U=[nn*3,0,0]
    for i in xrange(1,nn+1):
        U[De[i]]-=i
        U[Vers[i]]+=i      
        print "p =",i,"de ",'ABC'[De[i]],"vers ",'ABC'[Vers[i]],\
              "       * en A : %2i " % U[0],"* en B : %2i " % U[1],"* en C : %2i " % U[2],"*"
    print

# Programme principal
global sol
nmaxi,sol=5,0
De,Vers=[0]*(nmaxi+1),[0]*(nmaxi+1)
print "           ##########################"
print "           #    Début du calcul     #"
print "           ##########################"
print
nn=nmaxi
Urne=[nn*3,0,0]
niveaup(nn,1,Urne,De,Vers)
print
print "           #   Fin du calcul  #"

Alors pour nmaxi = 5, j'ai 2 solutions, pour 6 j'en ai 4, pour 7 j'en ai 16, pour 8 j'en ai 40, pour 9 j'arrive à 78...
Les urnes B et C (1 et 2 pour toi) étant interchangeables, il doit y avoir des solutions symétriques et donc non réellement diofférentes...
Je vais regarder tout ça, mais aussi tâcher d'améliorer le programme je n'ai que de la copie (presque) servile...

@+

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#8 27-04-2011 10:06:01

totomm
Invité

Re : [VBasic puis Python] Pour l'enigme "Vases communicants" de freddy

Bonjour,

Oui, il faudrait arriver à réduire les solutions en doublons (les urnes à 0 au départ sont interchangeables)
J'ai publié 56 et 104 solutions pour n = 8 et 9 mais avec des solutions où les 3 urnes étaient égales AVANT l'étape finale n.

Comme j'ai maintenant un algorithme (rapide) valable pour tout N (de la forme 3k-1, 3k ou 3k+1) qui utilise par récurrence des solutions "particulières" pour n de 6 à 20, j'incluerai la détermination de ces solutions de base dans l'algorithme général en Python que je publierai en mai

Cordialement

#9 11-05-2011 16:17:34

totomm
Invité

Re : [VBasic puis Python] Pour l'enigme "Vases communicants" de freddy

Bonjour,

@yoshi : Code promis. ATTENTION Python version 3.2
vous choisissez le nombre n en début du code.

Cordialement.

#Code pour PYTHON Version 3.2

# 3 urnes, 3*n billes,  Transfert de p billes pour p de 1 à n
#d'une urne dans une autre pour obtenir n, n, n dans les 3 urnes

nchoisi=45  #Nombre choisi

#*****************************************************************************
global dl # dernière ligne vue
global récurrence # un stack
#*****************************************************************************
def Voir(p,a,b,c,t, suite):
    # p est le Numéro du transfert (et son contenu), a b et c les urnes,
    # t contient les définitions des transferts,
    # suite =1 si une suite doit veir en remontant la récurrence
    if t[0]<0: print("n =",-t[0]," : Pas de solution")
    somme=a+b+c # somme de contrôle de validité
    q=len(t)-suite # nombre d'étapes à franchir
    for ii in range(p+1,p+q):
        v=t[ii-p]
        if v==1:    a,b = a-ii,b+ii #Codage des 6 mouvements possibles
        elif v==2:  a,c = a-ii,c+ii
        elif v==3:  b,c = b-ii,c+ii
        elif v==-1: a,b = a+ii,b-ii
        elif v==-2: a,c = a+ii,c-ii
        elif v==-3: b,c = b+ii,c-ii
        else: print("erreur de définition étape",ii)
        # Validité de chaque ligne
        if a<0 or b<0 or c<0 or (a+b+c)!=somme: Print("ERREUR, LIGNE NON VALIDE")
        print("p:%5i"%(ii),"  %5i"%a,"%5i"%b,"%5i"%c)
    return [p+q,a,b,c] #p+q est le numéro de l'étape suivante
#****************************************************************************    
def RèglesdeTransferts(nn):
    # nn est le numéro de la dernière ligne (contenu des urnes)
    # récurrence est un stack (global) qui contient les numéros de la récurrence

    global dl #dl[0] contient l'étape à atteindre,#dl[1] dl[2]et dl[3] les urnes a b et c
    global récurrence
   
    #Caractéristiques des 7 familles
    v=[0,0,2,2,4,4,3]
    ChangeBC=[0,1,0,1,0,1,1] # 1 si transfert entre b et c à la première étape

    #4 paramètres pour définir les règles
    k,i=(nn-3)//7,(nn-3)%7          # nn=7k+3+i
    pp=5*k+v[i] # pp Numéro de la récurrence
    bb=dl[2] # >0 si le coté utilisé était b (par opposition à c)
   
    # Définir T (de,vers) pour chaque famille pour la fonction Voir
    # indexer par i le codage des transferts
    tdébut0 = [[pp,2,2,2],[pp,-3,1,1,1],[pp,2,2],[pp,-3,1,1],
               [pp,2,2,2],[pp,-3,1,1],[pp,-3,1,1]]
    tdébut1 = [[pp,1,1,1],[pp,3,2,2,2],[pp,1,1],[pp,3,2,2],
               [pp,1,1,1],[pp,3,2,2],[pp,3,2,2]]
    moinsE =  [7,7,5,5,5,3,7]
    tmoins0 = [[-2,2],[-2,2],[2,-2],[2,-2],[-2,2],[2,-2],[2,-2]]
    tmoins1 = [[-1,1],[-1,1],[1,-1],[1,-1],[-1,1],[1,-1],[1,-1]]
    tfin0 =   [[-2,-2,-2,2,1],[-2,-2,-2,2,1],[-2,2,-2,1],[-2,2,-2,1],
              [-2,-2,1],[-2,1],[-2,2,-2,-2,2,1]]
    tfin1 =   [[-1,-1,-1,1,2],[-1,-1,-1,1,2],[-1,1,-1,2],[-1,1,-1,2],
              [-1,-1,2],[-1,2],[-1,1,-1,-1,1,2]]
   
    if bb==0:
        T = tdébut0[i] # -3 vaut (c vers b), 1 vaut (a vers b)
        if ChangeBC[i]: bb=1
    else:
        T = tdébut1[i] # 3 vaut (b vers c), 2 vaut (a vers c)
        if ChangeBC[i]: bb=0
    nbE=(nn-pp-moinsE[i]-ChangeBC[i])//2
    for j in range(0,nbE): #nbE fois
        if bb==0: T += tmoins0[i]
        else: T += tmoins1[i]
    # les dernières étapes pour arriver en n-1 sont ....
    # et (dernière ligne si pas de suite qui viendrait de la récurrence)
    if bb==0: T += tfin0[i]
    else: T += tfin1[i]
   
    if len(récurrence)==0:
        dl=Voir(pp-1,dl[1],dl[2],dl[3],T,0)
    else:
        dl=Voir(pp-1,dl[1],dl[2],dl[3],T,1)
    #print("dd",nn,k,i,pp,cvb,dl,récurrence) #constater le pop

#Programme principal********************************************
#Valeurs initiales pour n de 1 à 11.
transferts1_11 = [[-1],[-1],[-2],[3,1,1,2],[-4],[5,1,1,1,1,3],
    [6,2,1,1,3,-3,2],[7,1,2,2,-2,2,-3,2],[8,1,1,1,-1,1,-1,1,2],
    [9,1,1,1,2,3,2,-2,-3,2],[10,1,1,1,2,-1,2,2,-2,-3,2], \
    [11,1,1,1,1,1,-1,-1,1,-1,1,2]]            

v=[0,0,2,2,4,4,3] # caractérise les 7 familles
for n in range(nchoisi,nchoisi+1):
    if n>11:
        récurrence=[n]
        k,i=(n-3)//7,(n-3)%7
        nr=5*k+v[i]
        récurrence.append(nr)
        while nr > 11:
            k,i=(nr-3)//7,(nr-3)%7
            nr=5*k+v[i]
            récurrence.append(nr)
    if n>11:
        print("n =",n," : Total =",3*n,"   récurrence :",récurrence)
        while len(récurrence) > 0:
            popR=récurrence.pop()
            if popR<12:
                dl=Voir(0,3*n,0,0,transferts1_11[popR],1)
            else:
                RèglesdeTransferts(popR)
    else:
        print("n =",n," : Total =",3*n)
        dl=Voir(0,3*n,0,0, transferts1_11[n],0)

print("Fin du programme principal")

#10 12-05-2011 17:08:14

totomm
Invité

Re : [VBasic puis Python] Pour l'enigme "Vases communicants" de freddy

Bonsoir,

J'ai provoqué volontairement une erreur sur une urne et vu que dans le code de la procédure Voir, 3 lignes avant la fin, il y a Print au lieu de print (l'habitude des majuscules en VBasic...)
C'est la seule expression qui soit "inutilisée" dans ce programme.

Cordialement

#11 12-05-2011 18:37:45

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [VBasic puis Python] Pour l'enigme "Vases communicants" de freddy

salut,

Pas de lézard, j'avais vu le print.
Pas encore testé.
Mais en principe ton code en Python 2.6 ou 2.7 en remplaçant seulement print(blablabla) par print...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

Réponse rapide

Veuillez composer votre message et l'envoyer
Nom (obligatoire)

E-mail (obligatoire)

Message (obligatoire)

Programme anti-spam : Afin de lutter contre le spam, nous vous demandons de bien vouloir répondre à la question suivante. Après inscription sur le site, vous n'aurez plus à répondre à ces questions.

Quel est le résultat de l'opération suivante (donner le résultat en chiffres)?
soixante dix-huit plus quatre-vingt neuf
Système anti-bot

Faites glisser le curseur de gauche à droite pour activer le bouton de confirmation.

Attention : Vous devez activer Javascript dans votre navigateur pour utiliser le système anti-bot.

Pied de page des forums