Académique Documents
Professionnel Documents
Culture Documents
Bibm@th.net
Bibm@th
Accueil
Ressources
Collège
Lycée
Math Sup
Math Spé
Capes
Agreg interne
BTS
Bibliothèques
Bibliothèque d'exercices
Bibliothèque de problèmes
Références
Dictionnaire
Biographie de mathématiciens
Formulaire
Lexique français/anglais
Thèmes
Cryptographie et codes secrets
Jeux et énigmes
Carrés magiques
Mathématiques au quotidien
Dossiers
Forum
Ressources mathématiques > Base de données d'exercices > Exercices de théorie des graphes et d'algorithmique
>
Accéder à mon compte > Accéder à ma feuille d'exercices >
Indication
Corrigé
Nous donnons deux algorithmes.
Algorithme 1 :
n=0
H=0
Tant que (H<a) faire
n=n+1
H=H+1/n
Fin tant que
Afficher n.
Algorithme 2 :
n=1
H=0
Tant que (H<a) faire
H=H+1/n
n=n+1
Fin tant que
Afficher n-1.
Il faut bien remarquer la gestion différente de l'indice entre le premier et le deuxième algorithme, et
notamment le fait que l'on doit retourner dans le deuxième algorithme.
Exercice 2 - Maximum d'une suite [Signaler une erreur] [Ajouter à ma feuille d'exos]
Enoncé
On pose , et on admet que la fonction est croissante sur et décroissante sur
, où . Écrire un algorithme permettant de déterminer pour quelle valeur de l'entier le
nombre est maximal.
Indication
Corrigé
On parcourt les termes consécutifs de la suite jusqu'à observer une décroissance. Il faut faire bien
attention à l'initialisation (pour entrer dans la boucle) et à la sortie (afficher le rang précédent le dernier
que l'on a calculé).
VARIABLES :
p entier
r entier
u,v réel
Traitement
p=0,9
r=1
u=p^r-1/r
v=u
Tant que (u<=v) faire
u=v
r=r+1
v=p^r-1/r
Fin Tant Que.
Afficher r-1
Indication
Corrigé
Pour que soit une valeur approchée (par défaut) à près de , il suffit que
n=1
Répète
U=0
V=0
Pour k allant de 0 à n-1 faire
U=U+exp(-(k*k)/(n*n))/n
V=V+exp(-((k+1)*(k+1))/(n*n))/n
Fin pour
n=n+1
Jusqu'à ((V-U)<0.001)
Afficher U
Algorithmes en arithmétique
Exercice 4 - Renversant! [Signaler une erreur] [Ajouter à ma feuille d'exos]
Enoncé
Écrire une fonction qui prend en entrée un entier naturel et retourne cet entier écrit à l'envers. Par
exemple, si , la fonction devra retourner . On pourra utiliser les fonctions
quotient(n,p) et reste(n,p) qui donnent le quotient et le reste de la division de n par p.
Indication
Corrigé
L'idée est que si l'on prend le reste de a dans la division par 10, on récupère le dernier chiffre, et si on
prend le quotient, on récupère privé de son dernier chiffre. Il suffit d'itérer le procédé, en décalant à
chaque fois le résultat provisoire vers la gauche. Une solution est donc :
b=0
Tant que a>0 faire
b=10b+reste(a,10)
a=quotient(a,10)
Retourner b
1. Écrire une fonction d'argument deux entiers naturels non nuls et et renvoyant
True si divise , et False sinon.
2. Écrire une fonction d'argument un entier naturel , renvoyant si est
premier, et renvoyant sinon.
3. Écrire une fonction d'argument un entier naturel et renvoyant le nombre de nombres
premiers inférieurs ou égaux à .
Indication
Corrigé
1. On utilise le fait que divise si et seulement si le reste dans la division euclidienne de par
est nul.
def divise(p,q):
if ( (q%p) == 0):
return True
else:
return False
2. Un entier naturel est premier si ses seuls diviseurs positifs sont et lui-même, et s'il n'est pas
égal à . On sépare donc le traitement de , et pour les autres, on regarde si un des entiers entre
et divise .
def estpremier(p):
if (p<2):
return 0
for i in range(2,p):
if divise(i,p):
return 0
return 1
3.
def phi(n):
total=0
for m in range(2,n+1):
total+=estpremier(m)
return total
Indication
Corrigé
On notera Ent(x) la partie entière de x.
1. Écrire 21 en base 2.
2. Proposer un algorithme qui prend en entrée un entier et retourne son écriture en base 2.
Indication
Commencer par le dernier chiffre....
Corrigé
On continue avec 10 :
soit
On reprend avec 5 :
soit
soit finalement
Lire n
i=0
tant que (n>0) faire
l[i]=reste(n,2)
n=(n-l[i])/2
i=i+1
Fin tant que
Pour j allant de i-1 jusque 0 faire
Afficher l[j]
Fin tant que.
Simulations
Exercice 8 - Simulation d'une rangée de spots [Signaler une erreur] [Ajouter à ma feuille d'exos]
Enoncé
Une rampe verticale de spots nommés de bas en haut change d'état de la manière
suivante :
On pourra remarquer qu'à chaque instant, un et un seul spot est allumé. On note la variable
aléatoire représentant le premier instant (s'il existe) où le spot s'allume. Écrire un algorithme
simulant le fonctionnement de la variable aléatoire . On supposera que l'on dispose d'une fonction
ALEA(a,b) qui simule une loi uniforme discrète sur l'ensemble .
Indication
Utiliser deux variables : une désignant l'instant, et une désignant le spot allumé.
Corrigé
On va utiliser deux variables : instant qui désigne l'instant où l'on est, et qui désigne le spot allumé à
l'instant courant. Un algorithme possible est :
Variables :
k,instant entiers
Initialisation :
instant=0
k=1
Traitement
Tant que (k<>2) faire
instant=instant+1
Si k=1 faire k=ALEA(1,4)
sinon faire k=k-1
Fin Si
Fin Tant Que
Afficher instant
Indication
Corrigé
Voici une solution possible sous Python :
import random
def soiree(n,p):
c=0
for i in range(n):
if (random.random()<p):
c=c+1
return c
def repetitions(nb):
succes=0
for i in range(nb):
if (soiree(70,0.4)<=30):
succes=succes+1
return (succes/nb)
La fonction soiree(n,p) simule le déroulement d'une soirée et renvoie le nombre de crèmes brûlées
commandées au cours d'une soirée. La fonction repetitions(nb) propose de répéter un grand nombre de
soirées. Pour chaque soirée où le nombre de crèmes brûlées commandées est inférieur à 30, on
comptabilise un succès. On affiche ensuite la fréquence du nombre de succès. Une exécution de
repetitions(10000) donne environ 0,73. Le restaurateur semble avoir raison!
Remarquons qu'il est aussi possible d'avoir une résolution mathématique du problème. Le nombre de
crèmes brûlées commandé chaque soir est une variable aléatoire qui suit une loi binomiale de
paramètres et . L'énoncé nous demande de savoir si ce que l'on peut
déterminer facilement à l'aide d'un tableur.
Polynômes
Exercice 10 - Schéma de Horner [Signaler une erreur] [Ajouter à ma feuille d'exos]
Enoncé
Soit . Pour évaluer , le mathématicien anglais Horner a
proposé la méthode suivante :
Écrire une fonction sous Python qui prend en entrée la liste des coefficients d'un polynôme et un
nombre réel et qui retourne suivant la méthode de Horner.
Indication
Corrigé
Voici une fonction qui reproduit le fonctionnement du schéma de Hörner :
def horner(P,x):
n=len(P)
valeur=0
for i in range(n-1,-1,-1):
valeur=valeur*x+P[i]
return valeur
Il y a une petite subtilité ici, autour de la boucle : on fait décroître l'indice de (le degré du
polynôme) jusque 0 (mais il faut mettre -1 comme deuxième indice de la fonction range). On réalise en
fait comme première opération , puis , etc... d'où ce besoin de faire une
boucle où l'indice diminue.
Si le degré du polynôme est (qui est égal à dans notre fonction), notre fonction réalise
exactement additions et multiplications. On peut descendre à additions et
multiplications en modifiant un petit peu l'initialisation puis en faisant partir la boucle de :
def horner(P,x):
n=len(P)
valeur=P[n-1]
for i in range(n-2,-1,-1):
valeur=valeur*x+P[i]
return valeur
Récursivité
Exercice 11 - Coefficients binomiaux [Signaler une erreur] [Ajouter à ma feuille d'exos]
Enoncé
On rappelle que si , sont deux entiers naturels, le coefficient binomial vérifie
si .
.
si .
Écrire une fonction récursive permettant de calculer à partir des formules précédentes.
Indication
Corrigé
def binom(n,k):
if (k>n):
return 0
if (k==0) or (k==n):
return 1
return binom(n-1,k)+binom(n-1,k-1)
Exercice 12 - Une suite récurrente [Signaler une erreur] [Ajouter à ma feuille d'exos]
Enoncé
On considère une suite récurrente donnée par , , et les formules de récurrence :
1. Recopier et compléter la fonction récursive suivante, de sorte que suite(n) renvoie le couple
.
def suite(n):
if n==1:
return(1,3)
k=n//2
a,b=suite(....)
if n%2==0:
return (...,...)
else:
return (...,...)
2. Pour tout entier , exprimer en fonction de le nombre d'appels récursifs que réalise
suite(n).
Indication
1.
2. Encadrer entre et .
Corrigé
def suite(n):
if n==1:
return(1,3)
k=n//2
a,b=lucas4(k)
if n%2==0:
return (a*a+5,a*b+7)
else:
return (a*b+7,b*b+5)
Enoncé
L'algorithme d'exponentiation rapide est basé sur la remarque suivante : on a et
. Ainsi, pour calculer , il suffit de savoir calculer et de faire une multiplication,
et pour calculer , il suffit de savoir calculer et de faire deux multiplications. L'algorithme
suivant implémente récursivement l'algorithme d'exponentiation rapide sous Python :
def exporapide(a,n):
if n==0:
return 1
b=exporapide(a,n//2)
if (n%2)==1:
return b*b*a
else:
return b*b
Démontrer que, pour tout , le nombre total de multiplications effectuées par un appel à
exporapide(a,n) est inférieur ou égal à .
Indication
Procéder par récurrence forte sur .
Corrigé
On va procéder par récurrence forte sur . On fixe et pour tout , notons la propriété
"un appel à exporapide(a,n) effectue au plus multiplications".
Initialisation : exporapide(a,1) effectue deux multiplications, et .
Hérédité : On suppose que est vraie pour tout et on va prouver que est
vraie. On distingue alors deux cas :
ou bien est pair : dans ce cas, le nombre total de multiplications effectuées par exporapide(a,n)
est égal à 1 plus le nombre de multiplications effectuées par exporapide(a,n/2). Par hypothèse de
récurrence, le nombre total est inférieur ou égal à . Mais
et donc le nombre d'appels est majoré par
.
ou bien est impair : dans ce cas, exporapide(a,n) effectue deux muliplications et autant de
multiplications que exporapide(a,(n-1)/2). Par hypothèse de récurrence, le nombre total de
multiplications est donc majoré par
Lire a
Lire b
Tant que (b non nul) Faire
a=b
b=reste de a par b
Fin Tant que.
Afficher a.
Indication
Corrigé
L'algorithme ne fonctionne pas. En effet, imaginons qu'on entre dans la boucle Tant que avec et
. Après la première ligne du Tant que, on a et , puis, dès la deuxième ligne,
. Dans tous les cas, l'algorithme va renvoyer la valeur initiale de . Pour le corriger, il faudrait
introduire une troisième variable , et écrire le Tant que sous la forme suivante :
x=0
Pour t allant de 1 à 50 Faire
Si (random()<1/3) alors x=x+1
Si (random()>=1/3) et (random()<2/3) alors x=x+2
Si (random()>=2/3) alors x=x-3
Fin Pour.
Afficher x.
Cet algorithme fonctionne-t-il? Sinon, le corriger (la fonction random() retourne un nombre (pseudo)-
aléatoire entre 0 et 1).
Indication
Corrigé
L'algorithme ne fonctionne pas, car on utilise, dans la même itération de la boucle Pour, trois tirages
aléatoires différents. Rien ne dit que l'une des trois conditions sera remplie. Au contraire, les trois
conditions pourraient être remplies. Un algorithme correct est :
x=0
Pour t allant de 1 à 50 Faire
r=random()
Si (r<1/3) alors x=x+1
Si (r>=1/3) et (r<2/3) alors x=x+2
Si (r>=2/3) alors x=x-3
Fin Pour.
Afficher x.
Étudiant 2 :
a=0, b=0,c=0
Pour b allant de 0 à 10000
.
Si a+b+sqrt(c)<10000 et sqrt(c) entier alors afficher (a,b,sqrt(c))
c=0;
a=a+1;
Fin Pour.
Étudiant 3 :
Étudiant 4 :
Étudiant 5 :
a=0, b=0
Tant que a+b+sqrt(a*a+b*b)<=10000 faire
b=0
Tant que a+b+sqrt(a*a+b*b)<=10000 faire
Si Ent(sqrt(a*a+b*b))=sqrt(a*a+b*b) alors afficher (a,b,sqrt(a*a+b*b))
Fin si
b=b+1
Fin tant que
a=a+1
Fin tant que.
Étudiant 6 :
Indication
Corrigé
Analysons les algorithmes un par un. Celui de l'étudiant 1 est parfaitement correct. En effet, les boucles
permettent de parcourir tous les triplets (a,b,c) où a, b et c sont compris entre 0 et 10000, et le test
permet de n'afficher que les triplets qui correspondent aux conditions imposées.
Dans l'algorithme de l'étudiant 2, a et b n'évoluent pas indépendamment. Quand b vaut 0, a vaut 0,
quand b vaut 1, a vaut 1. L'algorithme ne donnera que les triplets pythagoriciens pour lesquels a=b.
Dans l'algorithme de l'étudiant 3, on ne teste pas si est un entier... L'algorithme 4 est correct
et plus efficace que le premier.
Le problème de l'algorithme de l'étudiant 5 est plus subtil. En effet, lorsqu'on sort du Tant Que
``imbriqué'', on a . On ne change pas la valeur de et on fait .
Ainsi, on a toujours , et on sort aussi du Tant Que ``externe''
immédiatement. On ne teste donc que les valeurs de pour lesquelles .
Enfin, l'algorithme de l'étudiant 6 comporte une boucle infinie. En effet, lorsque la condition
est remplie, alors on ne fait pas varier , et donc on boucle indéfiniment dans le Tant que
(cette condition d'ailleurs ne testerait pas que .
n:=2
u:=5/6
v:=7/12
Tant que u-v>0.001 faire
u=u-1/2n+1/(2n+1)
v=u-1/(2n+2)
Fin Tant que
Retourner u et v.
Étudiant 2 :
a=1
c=1/2
n=0
b=a
d=c
tant que (a-c>0.001) faire
n=n+1
b=a
a=b+(-1})/(2n+1)+1/(2n+2)
d=c
c=d+1/(2n+2)-1/(2n+3)
Afficher a et b
Étudiant 3 :
Entrées :
u=1
v=1/2
n=0
Traitement :
Étudiant 4 :
Variables : u,v,n,k
Initialisation :
u=1
v=1/2
k=0
n=0
Traitement :
Tant que (u-v>0.001) faire
Pour k allant de 1 à 2n faire
u=u+(-1)^k/k+1
Pour k allant de 1 à 2n+1 faire
v=v+(-1)^k/{k+1}
n=n+1
Sortie : Afficher u,v
Étudiant 5 :
Variables : a,b,n,u,v
Initialisation :
u=1
v=1/2
a=1/2
b=1
Traitement
Tant que (a>0.001)
n=n+1
a=1/(2n+2)
b=1/(2n+1)
u=v+b
v=u-a
Sortie : u,v
Étudiant 6 :
s=0
t=0
Pour k=0 à 1000 faire
s=s+(-1)^k/(k+1)
Fin Pour.
t=t+(-1)^(1001)/1002
Afficher s,t
Indication
Corrigé
Étudiant 1 : l'initialisation est étrange (pourquoi initialiser au rang 2), mais pourquoi pas? Le test d'arrêt
est correct, mais la valeur de n'est jamais changée. Les formules pour calculer u et v seraient
correctes (ce qu'on vérifie en exécutant les premières itérations de la boucle) si on ajoutait
avant la fin du Tant Que.
Étudiant 2 : le test est correct, l'utilisation des variables et est superflue. Elle donne l'impression
que l'étudiant n'a pas bien compris la notion de variable et ne sait pas que l'on peut faire .
Par ailleurs, le calcul de et de est erroné, comment le montre le calcul de la valeur de . Enfin, les
valeurs retournées ne doivent pas être et , mais et .
Étudiant 3 : Bonne séparation des parties de l'algorithme (même s'il s'agit plus de la phase dite
d'initialisation, ou de variables). On entre jamais dans la boucle (mauvais rôle joué par u et v). Dans la
boucle, le calcul de u et v est erroné : ou bien on ne rajoute que les termes manquants, ou bien on
calcule la somme, mais on ne l'ajoute pas à ce qui a déjà été calculé. De plus, on évite d'utiliser
l'instruction somme dans un algorithme (elle n'est pas disponible dans tous les langages de
programmation).
Étudiant 4 : Bonne séparation des parties de l'algorithme et stratégie différente pour calculer la somme.
Malheureusement, il faut réinitialiser les valeurs de u et de v à 0 au début du Tant Que pour que le
calcul fonctionne.
Étudiant 5 : La variable n'est pas initialisé (il faudrait l'initialiser à ). Sinon, cela fonctionne. Le
test est intéressant ainsi que la façon d'ajouter les termes. Là encore, pour se convaincre que
l'algorithme fonctionne, il faut le simuler avec les premières itérations.
Étudiant 6 : La démarche de cet étudiant est différente. Il calcule d'abord le nombre de termes de la
série qu'il faut calculer pour avoir une bonne approximation. Pour cela, il remarque qu'il veut que
et que . Il suffit donc de calculer et avec pour avoir
une bonne approximation. C'est ce que fait cet étudiant, qui calcule et .
Mathématicien du mois