Proposition de correction
from turtle import *
from math import *
from matplotlib . pyplot import *
import numpy as np
from random import *
X = [0, 3, 3, 1.5,0,0]
Y = [0, 0, 3, 5.5,3,0]
#plot (X, Y, "k-")
#Pour avoir la meme echelle sur les axes
axis('equal')
#show()
def tracerMaison():
forward(100)
left(90)
forward(100)
left(30)
forward(100)
left(120)
forward(100)
left(30)
forward(100)
def dessiner(unite,angle,motif):
# test de validité du mot
valide=['F','+','-']
for char in motif:
if char not in valide:
return 1
# Dessin
for char in motif:
if char=='F':
fd(unite)
if char=='+':
left(angle)
if char=='-':
right(angle)
# Le dessin est fini
return 0
def suivant(motif,regle):
sortie=''
for char in motif:
if char=='F':
sortie+=regle
else:sortie+=char
return sortie
def evolution(axiome,regle,etape):
#init
sortie=axiome
#on tourne sur le nb d'étapes:
for i in range(etape):
sortie=suivant(sortie,regle)
return sortie
def dessinerMPL(longueur,pasRotation,motif):
# on supose le mot valide
# Dessin
#init
x=[0]
y=[0]
d=90 #azimut
for char in motif:
if char=='F':
#on calcule les variations selon x et y
varx=longueur*np.cos(d*pi/180)
vary=longueur*np.sin(d*pi/180)
#on ajoute ces variations au dernier élément de la liste obtenu avec liste[-1]
x.append(x[-1]+varx)
y.append(y[-1]+vary)
if char=='+':
d+=pasRotation
if char=='-':
d-=pasRotation
plot (x, y, "k-")
#Pour avoir la meme echelle sur les axes
axis('equal')
show()
def dessinerRamif(unite,angle, motif,azimut):
#on Suppose le motif valide
x=[0]
y=[0]
d=azimut #azimut
pile=[]
for char in motif:
if char=='F':
#on calcule les variations selon x et y
varx=unite*np.cos(d*pi/180)
vary=unite*np.sin(d*pi/180)
#on ajoute ces variations au dernier élément de la liste obtenu avec liste[-1]
x.append(x[-1]+varx)
y.append(y[-1]+vary)
if char=='+':
d+=angle
if char=='-':
d-=angle
if char=='[':
# on sauvegarde la position courante dans la pile
pile.append([x[-1],y[-1],d])
if char==']':
# on dépile pour revenir à la posision sauvegardée
xpos,ypos,d=pile.pop()
x.append(xpos)
y.append(ypos)
plot (x, y, "k-")
#Pour avoir la meme echelle sur les axes
axis('equal')
show()
#PartieB
def genereRegle ():
alphabet = ['F', '-', '+', '[', ']']
regle = ""
for i in range (randint(15,20)):
regle=regle+choice(alphabet)
return regle
def verifie(motif):
pile=[]
for char in motif:
# on empile les [
if char=='[':
pile.append('[')
if char==']' :
if len(pile)==0:
return False
else :
pile.pop()
return len(pile)==0
#Q2b
def simplifie(regle):
i,reponse = 0,''
while i<len(regle)-1:
double=regle[i]+regle[i+1]
if double=='+-' or double=='-+':
i=i+2 # on saute le double qui a été traité
elif double == '-]' or double == '+]':
#on empile le crochet
reponse=reponse+regle[i+1]
i=i+2 # on saute le double qui a été traité
else:# si FF ou F[ ou ...
reponse=reponse+regle[i]
i=i+1
#on ajoute le dernier element du mot
if i==len(regle)-1: #erreur moi : ne pas ajouter syst. le dernier caractère (saut de 2 possible).
reponse = reponse + regle [-1]
if len(reponse)!= len(regle):
reponse=simplifie(reponse)
return reponse
def population(n):
resultat=[]
i=0
def comptage(char,chaine):
return chaine.count(char)
while i<n:
nouvelleRegle=simplifie(genereRegle())
if verifie(nouvelleRegle) and comptage('[',nouvelleRegle)>2 and (comptage('+',nouvelleRegle)+comptage('-',nouvelleRegle))>1 and nouvelleRegle not in resultat:
resultat.append(nouvelleRegle)
i+=1
return resultat
#Mutation
def mutation(chaine):
#reperage des symboles + ou -
listePositions=[]
for i in range(len(chaine)):
if chaine[i]=='+' or chaine[i]=='-':
listePositions.append(i)
#choix d'une position de symbole de rotation au hasard
j=randint(0,len(listePositions)-1)
alea=listePositions[j] # bornes incluses
#fonction d'echange des symboles
def echange(symbole):
if symbole=='+':
return '-'
if symbole=='-':
return '+'
#echange
#chaine de caractère non mutable !!!!
#liste mutable OK
print('tst')
print(chaine[0:alea])
print(echange(chaine[alea]))
print(chaine[alea+1:])
print('tst')
chaine1=chaine[0:alea]+echange(chaine[alea])+chaine[alea+1:]
return chaine1
def extraitBranche(chaine):
#1 on recherche les index de position des '['
#2 on choisit un des index au hasard : on note stop 1 son index.
#3 on cherche la position du caractère ']' qui suit : on note son index stop2
#4 on découpe la chaine en 3 brins que l'on retourne
#etape1
listePositions=[]
for i in range(len(chaine)):
if chaine[i]=='[':
listePositions.append(i)
#etape 2 : choix d'une position de '[' au hasard
j=randint(0,len(listePositions)-1)
stop1=listePositions[j] # bornes incluses
print(stop1)
#etape3
k=0
branche=chaine[stop1] # A ce stade elle n'est pas valide car = à '['
while not verifie(branche) :
branche=chaine[stop1:stop1+k+1]
print(branche)
k+=1
return chaine[0:stop1],branche,chaine[stop1+k:]
def croise(r1,r2):
br1,br2,br3=extraitBranche(r1)
br4,br5,br6=extraitBranche(r2)
enfant=br1+br5+br3
return enfant
##Programme principal
#tracerMaison()
#dessiner(5,60,evolution('F--F--F','F+F--F+F',2))
dessinerRamif(10,30,evolution('F','F[+FF]F[-FF]F',4),90)
#plante sympa
#dessinerRamif(10,40,evolution('F','F[+F]F[-F[+FF]]F',4),90)
# maison avec mpl
motif='+F+++++++++F++++++++'
#dessinerMPL(10,20,'F'+motif+'F'+motif)
dessinerRamif(10,20,'F[+F]F[-F]F',90)
#motif='[[][]'
#print(verifie(motif))
#regle='F+-+-[F-F]+F+[F+-FF]-F'
#print(simplifie(regle))
#print(mutation(regle))
print(extraitBranche('F[-FF]+[FF[-F]]-FF[-F-F]'))
print(croise('F[-FF]+[FFF]-FF[-F-F]','F[+F]+[-F-F]-FF[+F][-F][F]'))