informatique (tronc commun des prépas scientifiques) · Chapitre 1 · Exercice de TD
La boucle qui ne termine pas toujours
La discipline de programmation · niveau 3 (difficile)
Énoncé
Démontrer que la boucle suivante se termine pour tout entier :
def atteint_un(n: int) -> int:
c = 0
while n != 1:
if n % 2 == 0:
n = n // 2
else:
n = n + 1
c = c + 1
return c
Que se passe-t-il si l'on remplace n = n + 1 par n = 3 * n + 1 ?
Corrigé
- Première partie : Si est pair, en une étape, la valeur devient . Si est impair (), l'étape suivante produit (qui est pair) et l'étape d'après produit . Pour , on a . Ainsi, bien que la variable puisse augmenter ponctuellement d'une unité, sa valeur décroît strictement au bout de deux itérations successives au maximum. La suite des valeurs prises par toutes les deux étapes est strictement décroissante dans ; la boucle termine donc.
- Deuxième partie : Le remplacement par
3 * n + 1correspond à la conjecture de Syracuse. Pour cette version, il n'existe aucun variant connu ni aucune preuve générale de terminaison à ce jour.
Exercices semblables
- Variant non trivial — l'algorithme d'Euclide corrigé
- Invariant du maximum corrigé
- Le test de propriété corrigé
- Spécification, tests et preuve d'un algorithme corrigé
- Le flottant qui trahit le test corrigé