• Aucun résultat trouvé

Q def longueur_chaine(c): 025| n = 1 026| u = c 027| while u

N/A
N/A
Protected

Academic year: 2022

Partager "Q def longueur_chaine(c): 025| n = 1 026| u = c 027| while u"

Copied!
4
0
0

Texte intégral

(1)

# F:\informatiques\Python_MPSI\DM\suite_syracuse\dm_syracuse.py 001| # coding utf 8

002|

003|

#####################################################################

############################

004| # Corrigé du Devoir maison n°1: 2017-2018 Suite de Syracuse d'après Euler Project 14

005|

#####################################################################

################################

006|

007| ## Modules utilisés 008|

009| import time 010|

011|

012| ## Fonctions utilisées 013|

014|

015| # Q1 016| def f(n):

017| if n % 2 ==0:

018| return n//2 019| else:

020| return 3*n+1 021|

022| # Q2 023|

024| def longueur_chaine(c):

025| n = 1 026| u = c

027| while u != 1:

028| u = f(u) 029| n += 1 030| return n 031|

032| # Q3 033|

034| def max_chaine(c):

035| uMax = c 036| u = c

037| while u != 1:

038| u = f(u) 039| if u > uMax:

040| uMax = u 041| return uMax 042|

043| # Q4 044|

045| def longueur_maximale(N):

046| """Données N un entier strictement positif

047| Résultat: la plus grande longueur de chaîne et sa valeur de départ c parmi les chaînes dont la valeur de départ c est comprise entre 1 et N"""

1

(2)

048| longueur_max = 1

049| c_max = 1 # la valeur de départ de la chaîne de longueur maximale

050| for c in range(1, N+1):

051| longueur_actuelle = longueur_chaine(c) 052| if longueur_actuelle > longueur_max : 053| longueur_max = longueur_actuelle 054| c_max = c

055| return longueur_max, c_max 056|

057|

058| # Remarque:

059| '''Si l'on remplace ci-dessus le bloc for par le bloc ci-

dessous, on calcule deux fois longueur_chaine(c) au lieu de une seule fois. C'est moins efficace.

060| for c in range(1, N+1):

061| if longueur_chaine(c) > longueur_max:

062| longueur_max = longueur_chaine(c) 063| c_max = c

064| ''' 065|

066| ## Pour répondre à la question posée, on exécute le script suivant, qui donne en plus le temps de calcul

067|

068| t0 = time.clock()

069| print(longueur_maximale(10**6)) 070| t1 = time.clock()

071| duree_calcul = t1 -t0

072| print("temps de calcul ", duree_calcul) 073|

074| # renvoie (351, 77031) pour N = 10**5 en 3 s et (525,837799) pour 10**6 en 37s

075|

076| # Parmi les chaînes dont la valeur de départ c est comprise entre 1 et 10^6, la plus longue est obtenue pour une valeur de départ c = 837799, et sa longueur vaut 525.

077| # Le temps de calcul est de 37 secondes sur mon PC.

078|

079|

080| ## Améliorations possibles 081|

082| """On doit pouvoir accélérer les temps de calculs en mémorisant les calculs de longueurs de chaînes... On va gagner du temps en perdant de l'espace...

083| On crée un dictionnaire dans lequel, on va stocker au fur et à mesure les longueurs calculées (on note l(c) la longueur de la chaîne démarrant à c):

084| * Pour c = 2, 2 n'est pas encore dans le dico, on itère on tombe sur 1 qui est dans dico. Dans dico, on a maintenant les longueurs de 1 et 2.

085| * On passe à c =3. 3 n'est pas dans dico, on itère, on obtient 10 qui n'est pas dico, on continue jusqu'à ce l'on tombe dans le dico. On obtient ainsi comme chaîne [3, 10, 5, 16, 8, 4, 2]. On s'arrête à 2 car la longueur de 2 avait été calculée et vallait 2 086| On obtient non seulement la longueur de 3 mais aussi celles des

2

(3)

086| On obtient non seulement la longueur de 3 mais aussi celles des éléments de la chaîne: l(4) = 3, l(8)= 4, l(16)= 5, l(5) = 6, l(10) = 7 et l(3) = 8. On les enregistre alors dans le dico.

087| * Maintenant on passe au cas c= 4. Et bien il n'y a rien à faire car 4 est déjà dans le dico. De même pour c= 5.

088| * On passe donc à c = 6. La chaîne est [6,3], car 3 est dans le dico.

089| * On passe à c= 7. La chaîne est

[7,22,11,34,17,52,26,13,40,20,10], car 10 est dans le dico...

090| """

091|

092|

093| def longueur_maximale_bis(N):

094| dico_longueurs = {1: 1} # on initialise un dictionnaire contenant les longueurs des chaînes.

095| # La chaîne issue de 1 a pour longueur 1

096| longueur_max = 1 097| c_max = 1

098| for c in range(2, N+1):

099| t =[c] # t est un tableau qui va contenir les valeurs de la chaîne issue de c

100| u = c

101| while u not in dico_longueurs: # on calcule la chaîne jusquà ce que

102| # l'on tombe sur un nombre dont on connaît la longueur.

103| u = f(u) 104| t.append(u)

105| # arrivé ici u le dernier élément de t est dans dico, 106| # on met à jour le dico en rentrant les nouvelles longueurs des éléments de t

107| n = len(t)

108| for k in range(n):

109| dico_longueurs[t[k]] = dico_longueurs[u] + (n-1-k) 110| if dico_longueurs[t[k]] > longueur_max:

111| longueur_max = dico_longueurs[t[k]]

112| c_max = t[k]

113| return longueur_max, c_max 114|

115|

116| t0 = time.clock()

117| print(longueur_maximale_bis(10**7)) 118| t1 = time.clock()

119| duree_calcul = t1 -t0

120| print("temps de calcul ", duree_calcul) 121|

122| # renvoie (351, 77031) pour N = 10**5 en 0.4 s et (525,837799) pour 10**6 en 4 s

123| # C'est une jolie amélioration!!

124| # renvoie (686, 8400511) pour N = 10^7 en 41 s 125|

126|

127|

128| ## Attention à la division flottante n/ 2 au lieu de n//2 129| def f(n):

3

(4)

130| if n % 2 ==0:

131| return n/2 # on écrit n/2 au lieu de n//2 132| else:

133| return 3*n+1 134|

135| for c in [2**1024,2**10252]:

136| print( longueur_chaine(c)) 137|

138| """on obtient 1025 puis

139| OverflowError: integer division result too large for a float 140| car 2**1023 est la plus grande puissance de deux représentable par un nbre flottant"""

141|

142|

143|

4

Références

Documents relatifs

Qu'est-ce que l'étude précédente laisse penser de la propriété

On suppose que de toute suite extraite de u, on peut extraire une sous-suite qui converge vers l.. Déterminer la nature

Paternité-Partage des Conditions Initiales à l'Identique 2.0 France disponible en ligne http://creativecommons.org/licenses/by-sa/2.0/fr/.. 2 Rémy

En utilisant la question 3a, montrer que le module d'une valeur propre est inférieur ou égal à 1.. En formant une équation diérentielle, déterminer le spectre

Cours de Frédéric Mandon sous licence Creative Commons BY NC SA, http://creativecommons.org/licenses/by-nc-sa/3.0/fr/1. • La symétrie par rapport à la première bissectrice

[r]

[r]

[r]