Boucle while

\(\newcommand{\ds}{\displaystyle}\) \(\newcommand{\Frac}{\ds\frac}\) \(\renewcommand{\r}{\mathbb{ R}}\) \(\newcommand{\C}{\mathbb{ C}}\) \(\newcommand{\n}{\mathbb{ N}}\) \(\newcommand{\z}{\mathbb{ Z}}\) \(\newcommand{\Q}{\mathbb{ Q}}\) \(\newcommand{\N}{\mathbb{ N}}\) \(\newcommand{\n}{\mathbb{ N}}\) \(\newcommand{\ol}{\overline}\) \(\newcommand{\abs}[1]{\left| \,{#1} \right|}\) \(\newcommand{\pv}{\;;\;}\) \(\newcommand{\ens}[1]{\left\{ {#1} \right\}}\) \(\newcommand{\mens}[1]{\setminus\left\{ {#1} \right\}}\) \(\newcommand{\Par}[1]{\left({#1}\right)}\) \(\newcommand{\pe}[1]{\left\lfloor {#1} \right\rfloor}\) \(\newcommand{\trans}[1]{\,^t\!{#1}}\)

Boucle while

Cours

Boucle while

Un problème typique

Étant donné un entier \(n\), on cherche un entier noté \(m\) qui soit le premier multiple de 10 supérieur ou égal à \(n\). Si par exemple \(n=42\) alors \(m=50\) : en effet, 50 est bien un multiple de 10 et il n’y en pas d’autre entre 42 et 50. Voici d’autres exemples :

\(n\) 2038 420 0
\(m\) 2040 420 0
L’idée à implémenter

Les multiples de 10 sont les entiers : \(0, 10, 20, 30\) etc. Ils s’écrivent sous la forme \(10k\)\(k\) varie à partir de 0.

Pour trouver \(m\), on parcourt les multiples de 10 depuis 0 et on s’arrête une fois qu’on a atteint ou dépassé l’entier \(n\) donné. Autrement dit, on énumère les multiples \(m\) de 10 tant que \(m < n\). Le parcours est montré dans le tableau ci-dessous où on suppose que \(n=42\).

\(k\) 0 1 2 3 4 5
\(10k < 42\) ? oui oui oui oui oui non

Implémentation en Python

L’idée de « tant que », « jusqu’à ce que », « aussi longtemps que » est traduite dans le code Python par l’instruction while (qui veut dire « tant que » en anglais).

Le code suivant répond au problème posé :

while_typique.py

1
2
3
4
5
6
7
n = 42
k = 0

while 10 * k < n:
    k = k + 1

print(10 * k)
8
50

On voit (cf. lignes 7 et 8) que la solution au problème est 50.

Analyse de code

On passe en revue le code de while_typique.py.

Vocabulaire de la boucle while
  • Lignes 4-5 : ces deux lignes forment une seule et même instruction, dite instruction while.
  • Ligne 4 : l”en-tête de la boucle while est la partie qui commence avec while et se termine avant le séparateur : (deux-points).
  • Ligne 5 : le corps de la boucle while qui est le bloc indenté sous les deux-points.
Répétition

Une boucle while répète une action (ligne 5) tant qu’une condition, ici (cf. ligne 4) :

10 * k < n

reste vraie. Plus précisément,

  • si la condition est vraie, l’exécution entre dans le corps de la boucle et à la fin du corps de la boucle, la condition est à nouveau testée (d’où le terme de boucle)
  • si la condition est fausse, l’exécution du programme va au-delà du corps de la boucle, ici à la ligne 6.
Variable de contrôle

Une boucle while fait souvent appel à une variable de contrôle, ici k, qui évolue pendant la boucle. Typiquement,

  • cette variable est initialisée avant la boucle, ici ligne 2 ;
  • cette variable est réaffectée, dans le corps de la boucle while, ici par l’instruction ligne 5 ;
  • la condition à tester (ici ligne 4) est différente d’un tour de boucle à l’autre car elle dépend de k qui, entre-temps, a varié.
Remarques
  • Ligne 4 : dans l’immense majorité des cas, le corps d’une boucle while est indenté.
  • Ligne 1 : il est possible de faire d’autres essais de code en changeant juste la valeur de \(n\). Par exemple, si on change \(n\) en 2038, le programme affichera 2040.
  • Il se peut que l’exécution du code n’entre même pas dans le corps de la boucle while. Par exemple, si ligne 1, on choisit n=0 au lieu de n=42, le test 10 * k < n (ligne 4) échoue immédiatement et donc le programme continue à la ligne 6 sans même passer par la ligne 5.
  • À la différence de la syntaxe des boucles while du C et de Java, le booléen évalué avant chaque tour de boucle n’a pas besoin d’être entouré de parenthèses.

Comprendre comment s’exécute une boucle while

Modifions le code précédent while_typique.py pour mieux comprendre l’exécution de la boucle while:

while_typique_affichage.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
n = 42
k = 0
print("avant while", "-> k=", k)
print()

while 10 * k < n:
  print("debut while", "k=", k, "-> 10*k=", 10*k)
  k = k + 1
  print("fin while", "-> k=", k)
  print()
print("apres while")
print(10 * k)
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
avant while -> k= 0

debut while k= 0 -> 10*k= 0
fin while -> k= 1

debut while k= 1 -> 10*k= 10
fin while -> k= 2

debut while k= 2 -> 10*k= 20
fin while -> k= 3

debut while k= 3 -> 10*k= 30
fin while -> k= 4

debut while k= 4 -> 10*k= 40
fin while -> k= 5

apres while
50

En plus du code initial, while_typique_affichage.py contient des instructions d’affichage (lignes 3, 7, 9 et 11) et des instructions de sauts de ligne (lignes 4 et 10) dans la sortie pour observer l’évolution de k et de 10 * k avant, pendant et après la boucle while.

L’exécution du programme est la suivante :

  • Lignes 2 et 7 : la valeur de k avant le commencement de la boucle while
  • Ligne 6 : k vaut 0. Le test de la boucle while est effectué : a-t-on 0 < 42 ? La réponse est oui donc, l’exécution du code continue dans le corps de la boucle while
  • Les affichages sont effectués : k est changé de 0 à 1 (lignes 8 et 16).
  • Ligne 6 : le test de la boucle while est à nouveau effectué : a-t-on \(10 < 42\) ? La réponse est oui et l’exécution entre à nouveau dans le corps de la boucle. Cette opération se répète jusqu’à ce que k = 5 (ligne 8 et ligne 28).
  • Ligne 6 : le test de la boucle while est effectué : a-t-on \(50 < 42\) ? Cette fois, la réponse est non donc l’exécution quitte la boucle et continue lignes 11 et 12, cf. lignes 30 et 31.
  • Ligne 12 : le résultat affiché (cf. ligne 31) est bien le résultat demandé. Comme le test 10 * k < n a échoué pour la première fois, c’est qu’on a 10 * k >= n avec k minimal et c’est bien ce que l’on cherchait.

Boucle for vs boucle while

Python dispose de deux types de boucle : la boucle for et la boucle while. Elles ont chacune des usages spécifiques.

Usage canonique de la boucle for

La boucle for s’emploie si :

  • une action doit être effectuée un nombre prédéterminé de fois, et, surtout, connu avant l’exécution de la boucle. Par exemple, s’il faut afficher 42 nombres vérifiant une certaine propriété, on utilise une boucle du type for i in range(42).
  • on parcourt une liste entre deux indices connus à l’avance, ce qui peut être la totalité de la liste ou, par exemple, de la 5ème position à l’avant-avant dernière.

Par exemple, étant donné une liste L de nombres, si on cherche à déterminer combien L contient d’entiers positifs, on utilisera une boucle d’en-tête du type for x in L ou encore for i in range(len(L)).

Usage canonique de la boucle while

La boucle while s’emploie si une action doit être répétée tant qu’une certaine condition reste vraie et sans qu’on sache à l’avance combien de fois la boucle va être répétée. Par exemple,

  • on a une liste d’entiers et on cherche le premier entier de la liste qui soit pair ;
  • on cherche la plus petite puissance de 10 qui dépasse un entier donné.

De même, le codage d’une situation utilisant les termes « dès lors que », « à partir du moment où » nécessitent souvent d’employer une boucle while. Par exemple, si on donne une liste L d’entiers et qu’on demande de faire la somme dès éléments x de L dès lors que x>0, il va s’agir de parcourir la liste L jusqu’à ce que ses termes soient négatif ou nuls et ne commencer la somme qu’une fois la boucle while interrompue.

Usage inapproprié d’une boucle while

Le programme ci-dessous utilise une boucle while pour afficher les 5 premiers multiples de 10 :

1
2
3
4
5
6
i = 1
while i <= 5:
  print(10 * i)
  i = i + 1

print("Fin")
 7
 8
 9
10
11
12
10
20
30
40
50
Fin

Le code while_inapproprie.py est un usage non recommandé de la boucle while. En effet, le code contient des instructions inutiles par rapport à une boucle for :

  • Ligne 1 : initialisation inutile, c’est automatique avec une boucle for.
  • Ligne 2 : test de condition, automatique avec la boucle for.
  • Ligne 4 : incrémentation inutile, c’est automatique avec une boucle for.

Comparer avec un code équivalent écrit avec une boucle for :

1
2
3
4
for i in range(5):
    print(10 * i)

print("Fin")

Boucle while et parcours de liste

Usuellement, le parcours d’une liste est associé à une boucle for. Toutefois, dans certaines circonstances, il est plus approprié de parcourir une liste avec une boucle while.

Soit à définir un code Python qui, partant d’une liste L d’entiers détermine si L ne contient que des entiers positifs. Plus précisément, le code doit définir un booléen nommé tousPositifs qui vaut True si L ne contient que des entiers positifs et False sinon.

L’idée est de parcourir la liste L avec une boucle while à l’aide d’un indice i valide et tant que le terme courant L[i] est positif ou nul :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
L= [31, 82, -42, 32, -81]

i=0
n = len(L)

while i<n and L[i]>=0:
    i = i + 1

tousPositifs = (i==n)

print(L, tousPositifs)
12
[31, 82, -42, 32, -81] False
  • Ligne 6 : la condition doit D’ABORD gérer la sortie de liste d’où la condition i < n qui évite le débordement d’indice.

  • Ligne 6 : la condition doit aussi filtrer suivant le critère, ici le fait que chaque terme soit positif.

  • Ligne 9 : Il s’agit de définir le booléen.

    • Si un élément négatif est apparu dans la liste, soit i son indice. Alors comme le booléen i<n and L[i]>=0 vaut False (puisque L[i]<0), la boucle while s’arrête et l’indice i vérifie i<n.
    • En revanche, si aucun élément de la liste n’est strictement négatif, le corps de la boucle while sera exécuté tant que la condition i<n sera vraie. Lorsque i = n-1, le corps de la boucle est exécuté et i devient i+1 donc i=n et la boucle se termine.

    Donc, ce qui différencie les deux cas, c’est la valeur de i en sortie de boucle : dans le second cas, i vaut n et pas dans le premier cas, ce qui explique la définition ligne 9 de tousPositifs.

Même si c’est un détail, noter que le code suivant devrait être évité :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
L= [31, 82, -42, 32, -81]

i=0

while i< len(L) and L[i]>=0:
    i = i + 1

tousPositifs = (i==len(L))

print(L, tousPositifs)
  • Ligne 5 : à chaque tour de boucle, l’appel len(L) est recalculé alors que len(L) est un nombre qui ne varie pas.

Boucle for vs boucle while : tableau récapitulatif

Utiliser une boucle while par rapport à une boucle for nécessite plus de soin comme le résume le tableau ci-dessous :

  Boucle while Boucle for
Initialisation indice i manuelle automatique (en-tête de la boucle)
Incrémentation de l’indice i manuelle automatique
Sortie de boucle manuelle (avec drapeau dans l’en-tête) nécessite des instructions de saut (break, return)
Sortie de liste de longueur n manuelle (i<n) automatique

Exercice type : La petite exponentielle contre le grand produit

Trouver le plus grand entier \(n >0\) tel que \(1.0001^n<10000n\) (on trouvera \(n=214893\)).

Solution

Posons a = 1.0001. Comme a est très proche de 1, les puissances de a augmentent mais très lentement. Par exemple :

1
2
a=1.0001
print(a**10000)
3
2.7181459268249255

Toutefois, comme a est strictement plus grand que 1, le nombre \(\mathtt{a^n}\) peut être rendu aussi grand que l’on veut en choisissant \(\mathtt{n}\) assez grand.

Pour le code lui-même, l’idée est très simple : on compare \(\mathtt{a^n}\) et \(\mathtt{10000\times n}\) en faisant varier \(\mathtt{n}\) suivant les entiers consécutifs jusqu’à ce que le premier dépasse le second. D’où le code :

1
2
3
4
5
6
k=1

while 1.0001**k < 10000*k:
    k=k+1

print("n =", k-1)
7
n = 214893
  • Ligne 1 : l’énoncé demande de trouver un entier \(\mathtt{k > 0}\).
  • Ligne 6 : en sortie de boucle while l’entier k trouvé est le premier qui vérifie \(\mathtt{1.0001^k \geq 10000\times k}\). C’est l’entier k précédent qui est tel que l’en-tête de la boucle while est vrai. C’est donc lui la solution du problème.

On peut bien sûr vérifier que le résultat n = 214893 est conforme :

1
2
3
4
5
k = 214893
print(k, "->", 1.0001**k < 10000*k)

k = 214894
print(k, "->", 1.0001**k < 10000*k)
6
7
214893 -> True
214894 -> False

Exercice type : Premier entier pair

Ecrire un code qui à partir d’une liste L d’entiers :

  • affiche le premier entier pair rencontré dans la liste L si L contient au moins un entier pair,
  • affiche le nombre \(-1\) s’il n’existe aucun entier pair dans la liste.

Voici quelques exemples de comportement du programme :

1
2
3
4
5
6
7
8
[1, 3, 42, 51, 32, 9] -> 42
[1, 3, 42, 51, 33] -> 42
[1, 3, 51, 33] -> -1
[1, 3, 51, 33, 42] -> 42
[42, 82] -> 42
[42] -> 42
[81] -> -1
[] -> -1

Solution

Version for

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
L=[1, 3, 41, 51, 31, 9]
ok=False
i=0
n=len(L)

for i in range(n):
    if L[i]%2==0 and not ok:
        print(L[i])
        ok=True
if not ok:
    print(-1)

Il suffit d’appliquer la technique vue dans le paragraphe Boucle while et parcours de liste.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
L=[1, 3, 42, 51, 32, 9]

i=0
n=len(L)

while i<n and L[i]%2 == 1:
    i = i + 1

if (i==n):
    print(L, "->", -1)
else:
    print(L, "->", L[i])
13
[1, 3, 42, 51, 32, 9] -> 42
  • Lignes 6-7 : la boucle while parcourt la liste L jusqu’à ce que la liste soit épuisée ou bien qu’un élément pair soit rencontrée.
  • Lignes 9-10 : en sortie de boucle, ou bien l’indice i est hors de la liste et dans ce cas la liste ne contient aucun élément pair (si un élément pair est présent uniquement en dernière position alors, en sortie de boucle, i vaut n-1.

Pour traiter le cas de plusieurs listes, au lieu de recopier du code, on place les liste dans une liste tests et on parcourt la liste tests pour tester chacune des lignes :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
tests = [
[1, 3, 42, 51, 32, 9],
[1, 3, 42, 51, 33],
[1, 3, 51, 33],
[1, 3, 51, 33, 42],
[42, 82],
[42],
[81],
[]]

for L in tests:
    i=0
    n=len(L)

    while i<n and L[i]%2 == 1:
        i = i + 1

    if (i==n):
        print(L, "->", -1)
    else:
        print(L, "->", L[i])
22
23
24
25
26
27
28
29
[1, 3, 42, 51, 32, 9] -> 42
[1, 3, 42, 51, 33] -> 42
[1, 3, 51, 33] -> -1
[1, 3, 51, 33, 42] -> 42
[42, 82] -> 42
[42] -> 42
[81] -> -1
[] -> -1

Exercices

Somme harmonique dépassant 18

Trouver le plus petit entier n tel que \(1+\frac 12 +\frac 13+\dots +\frac 1n > 18\).

ppcm

Construire une variable ppcm qui référence le plus petit commun multiple de deux entiers donnés \(a\) et \(b\). Par exemple, si les entiers sont \(a=16\) et \(b=60\) alors ppcm = 240 puisque si on liste les multiples de \(a\), on obtient \(16, 32, 48, 64, 80, \dots\) et les multiples de \(b\) d’autre part, à savoir \(60, 120, 180, \dots\) et la plus petite valeur commune entre ces listes est 240.

Il est attendu d’écrire une version « naïve » (et non pas d’utiliser l’algorithme d’Euclide pour obtenir d’abord le pgcd). La version naïve consistera par exemple à examiner les multiples non nuls de a et à tester jusqu’à ce qu’un de ces multiples soit multiple de b.

Même avec un code « naïf », vous devez pouvoir traiter des entiers a et b de l’ordre de un million.

Restes chinois

Soit n le plus petit entier vérifiant les deux propriétés suivantes :

  • si on divise n par 2042, on obtient 2040 pour reste
  • si on divise \(\mathtt{n}\) par 2043, on trouve 2041 pour reste.

Trouver bestialement n avec une boucle while.

Diviser par deux ou retirer 1

Observez le motif ci-dessous formé de 10 entiers. On part d’un entier \(a> 0\), ici \(a=81\), et on construit une suite d’entiers ainsi :

81 80 40 20 10 5 4 2 1 0.

Le procédé de construction est défini ainsi :

  • si l’entier \(x\) est pair, le successeur de \(x\) de la suite est la moitié de \(x\)
  • sinon, ce successeur est \(x-1\) ;
  • la suite se termine dès qu’un élément de la suite vaut 0.

Par exemple, dans la suite ci-dessus, le successeur de 80 est 40 car 80 est pair et que sa moitié est 40, et de même le successeur de 5 est 4 car 5 est impair et que \(4=5-1\).

  1. On vous donne un entier \(a\geq 0\) et on vous demande d’afficher la suite générée à partir de \(a\) et de calculer la longueur de la suite ainsi générée. Par exemple, si \(a=79\) vous devez afficher la suite suivante :

    79 78 39 38 19 18 9 8 4 2 1 0
    

    et la longueur à calculer est de 12.

  2. Parmi toutes les listes commençant par un entier entre 0 et 1000, quelle est la longueur maximale d’une suite ?

Soustraire jusqu’à équilibre

On donne deux entiers strictement positifs \(\mathtt{a}\) et \(\mathtt{b}\). On répète l’action consistant à soustraire le plus petit des deux nombres au plus grand des deux jusqu’à ce que les deux nombres soient égaux. Ci-dessous, le déroulement de la répétition si au départ \(\mathtt{a=5}\) et \(\mathtt{b=7}\):

 a b
------
 5 7
 5 2
 3 2
 1 2
 1 1

Ecrire un code qui exécute le programme décrit ci-dessus et détermine le nombre total de soustractions. Dans l’exemple, ce nombre est de 4 soustractions : \(\mathtt{7 -5}\) puis \(\mathtt{5 -2}\) puis \(\mathtt{3 -2}\) et enfin \(\mathtt{2 -1}\).

Cet exercice a été proposé sur le forum Python d’OpenClassrooms.

Divisions successives par deux

On part d’un entier n>1 et :

  • s’il est pair, on le divise par 2
  • s’il est impair, on lui ajoute 1 et on divise par 2.

Si par exemple n=42 on obtient 21 et si n=99 on obtient 50.

Maintenant, on répète ce procédé jusqu’à ce que le nombre obtenu vaille 1. On demande d’écrire un code qui détermine le nombre de divisions effectuées.

Par exemple, si n=25, les différentes étapes seront :

13
7
4
2
1

et le nombre de divisions effectuées est 5.

Tirage du loto

Écrire un code qui crée un tirage aléatoire des 5 numéros d’un loto. On rappelle qu’un tirage de loto est formée de 5 numéros distincts entre 1 et 49. On ne tirera pas de « numéro Chance ».

Ainsi, le code pourra générer une liste telle que [42, 32, 48, 47, 20] mais pas telle que [42, 32, 48, 42, 20] puisque dans cette dernière liste, le numéro 42 apparaît deux fois.

On utilisera une boucle while pour placer au fur et à mesure les numéros tirés dans une liste L initialement vide. On rappelle que si L est une liste d’entiers et x un entier alors l’expression x in L vaut True si l’entier x est dans la liste L et False sinon.

Calculer le nombre de chiffres d’un entier

On donne un entier \(\mathtt{n\geq 0}\) et on cherche le nombre de chiffres de \(\mathtt{n}\) (ce nombre de chiffres sera appelé nchiffres). Par exemple, si \(\mathtt{n = 2020}\) alors nchiffres = 4 ou encore si \(\mathtt{n = 42}\) alors nchiffres = 2.

L’idée pour calculer nchiffres est de compter le nombre de divisions successives de n par 10 jusqu’à ce que le quotient (entier) soit nul. Par exemple

  • le quotient entier de 2020 par 10 est 202,
  • le quotient entier de 202 par 10 est 20,
  • le quotient entier de 20 par 10 est 2,
  • le quotient entier de 2 par 10 est 0.

C’est parce 2020 a justement 4 chiffres qu’on a effectué 4 divisions successives par 10 avant d’obtenir un quotient nul.

Ecrire un code Python utilisant une boucle while et qui détermine nchiffres connaissant \(\mathtt{n}\).

Voici quelques exemples de comportements

42 -> 2
2020 -> 4
10 -> 2
7 -> 1
0 -> 1
741520036365253625145211741523636854198541 -> 42

Nombre de chiffres d’un entier

Soit un entier \(\mathtt{n\geq 0}\) et soit \(\mathtt{N}\) le nombre de chiffres de \(\mathtt{n}\). Par exemple, si \(\mathtt{n=25420}\) alors \(\mathtt{N=5}\).

On veut écrire un code qui détermine \(\mathtt{N}\) avec la méthode suivante et qu’on va illustrer sur l’exemple de \(\mathtt{n=25420}\). On calcule les puissances \(\mathtt{10^k}\) donc \(1\), \(10\), \(100\), etc jusqu’à ce que \(\mathtt{10^k>25420}\), ce qui s’obtient pour pour \(\mathtt{k=5}\) puisque \(\mathtt{10^5=100000>n}\) et le nombre de chiffres de \(\mathtt{n}\) est alors \(\mathtt{k=5}\)

En appliquant cette méthode à l’aide d’une boucle while, écrire un programme qui calcule le nombre de chiffres de n.

Nombre de zéros qui terminent un entier

On donne un entier \(\mathtt{n\geq 0}\), par exemple \(\mathtt{n=4205000}\) et on demande de déterminer le nombre de zéros qui terminent l’écriture décimale du nombre ; dans l’exemple précédent, ce nombre est 3. On pourra remarquer que c’est l’exposant de la plus grande puissance de 10 dont \(\mathtt{n}\) soit multiple. On utilisera obligatoirement une boucle while. Ne pas oublier le cas \(\mathtt{n=0}\).

Inverser l’écriture d’un nombre

On donne un entier, par exemple n = 25048 et on demande de construire l’entier m, dans l’exemple \(\mathtt{m=84052}\), dont l’écriture décimale est celle de \(\mathtt{n}\) mais inversée. Le nombre \(\mathtt{n}\) peut se terminer par des zéros, par exemple si \(\mathtt{n=25000}\) alors \(\mathtt{m=52}\).

L’algorithme à utiliser est illustré sur le cas de n = 25048. Au départ, on dispose d’une variable s=0 et qui va évoluer en prenant les valeurs des différents nombres inversés, dans notre cas, il s’agira de :

\(8,\quad 84, \quad 840,\quad 8405,\quad 84052\).

On pourra remaquer que chaque valeur de \(\mathtt{s}\) s’obtient en multipliant par 10 la précédente et en ajoutant un chiffre de \(\mathtt{n}\) ; par exemple, \(\mathtt{8405}\) s’obtient par \(\mathtt{840\times 10 + 5}\).

On fera des divisions successives de n par 10, en utilisant à chaque fois le quotient et le reste. Le code utilisera une boucle while et qui se terminera lorsque le quotient courant par 10 vaudra 0.

Cet exercice est repris d’un exercice du site d’apprentissage AlgoPython.

Etre un entier léger

Un entier strictement positif sera dit « léger » si tous ses chiffres, sauf le premier, sont nuls. Par exemple, les entiers 7000, 40 ou 5 sont légers tandis que 2200, 50050 ou 42 ne le ont pas. Etant donné un entier strictement positif n, écrire un code utilisant une boucle while et créant un booléen estLeger qui vaut True si n est un entier léger et False sinon. On pourra diviser n par 10 tant que le quotient est encore multiple de 10. Tester sur tous les entiers donnés en exemple ci-dessus.

Placement dans une suite croissante

On donne une liste \(\mathtt{L}\) croissante d’entiers ainsi qu’un entier \(\mathtt{x}\).

On demande de construire le nombre \(\mathtt{k}\) d’éléments \(\mathtt{y}\) de L tels que \(\mathtt{y\leq x}\). On utilisera une boucle while.

Ci-dessous, quelques exemples de comportements attendus :

L = [33, 36, 56, 76, 88], x = 62
k = 3
--------------
L = [33, 36, 62, 62, 76, 88], x = 62
k = 4
--------------
L = [33, 36, 62, 62], x = 62
k = 4
--------------
L = [33, 36, 62, 62], x = 21
k = 0
--------------
L = [42], x = 81
k = 1
--------------
L = [81], x = 42
k = 0
--------------
L = [42], x = 42
k = 1
--------------

Insertion dans une suite croissante

On donne une liste \(\mathtt{L}\) croissante de n entiers ainsi qu’un entier \(\mathtt{x}\).

On demande de construire une nouvelle liste M croissante, formée des n entiers de L ainsi que de x mais placé convenablement pour que la liste obtenue soit toujours croissante. On utilisera une boucle while.

Ci-dessous, quelques exemples de comportements attendus :

L = [1, 3, 7, 7, 8], x = 5
M = [1, 3, 5, 7, 7, 8]
--------------
L = [1, 2, 3], x = 2
M = [1, 2, 2, 3]
--------------
L = [1, 2, 8, 8], x = 0
M = [0, 1, 2, 8, 8]
--------------
L = [0], x = 5
M = [0, 5]
--------------
L = [5], x = 0
M = [0, 5]
--------------

Pas d’impair

Soit une liste L formée d’entiers. Écrire, à l’aide d’une boucle while, un booléen queDesPairs traduisant que L ne contient que des entiers pairs.

Comportement attendu :

[82, 31, 82] -> False
[82, 12, 46] -> True
[82] -> True
[81] -> False

Liste d’entiers en miroir

On donne une liste L d’entiers, par exemple L = [4, 2, 2, 4] et on demande d’écrire une variable booléenne estEnMiroir qui vaut True si cette liste est en miroir, autrement dit si

  • le premier et le dernier élément de L sont égaux,
  • le deuxième et l’avant-dernier élément de L sont égaux,
  • et ainsi de suite jusqu’à épuisement de la liste.

Dans le cas de la liste L = [4, 2, 2, 4] ou encore L = [4, 2, 4], la liste est en miroir. Dans le cas de la liste L = [4, 2, 1], la liste n’est pas en miroir.

Votre code doit impérativement utiliser une boucle while pertinente.

Listes « opposées » (boucle while)

Ecrire un code qui partant deux listes d’entiers L et M, de même longueur, crée un booléen sontOpposees valant True si les deux listes sont « opposées » et False sinon. Deux listes sont considérées comme « opposées » si, à des indices identiques, elles possèdent des éléments opposés (comme -81 et 81). Voici quelques exemples de comportements attendus :

[81, -12, 0, -81, -31] [-81, 12, 0, 81, 31] -> True
                                 [-81] [81] -> True
                              [0, 0] [0, 0] -> True
                                    [ ] [ ] -> True
                       [81, -12] [-81, -12] -> False
                     [-81, 12, 0] [81, -12] -> False

Vous ne devez pas utiliser de boucle for mais une boucle while

Liste en miroir opposé

La liste [-42, 2016, 2020, -2020, -2016, 42] sera dite une liste en miroir opposé : si on énumère la liste de la gauche vers la droite, c’est comme si on énumérait de la droite vers la gauche la liste des OPPOSÉS.

On vous donne une liste non vide d’entiers est vous devez construire un booléen miroirOpp qui vaut True si L est une liste d’entiers en miroir opposé et False sinon. Voici quelques exemples de comportements attendus :

[1, -2, -5, 3, -3, 5, 2, -1] -> True
[1, -2, -5, 3, 0, 0, 0, -3, 5, 2, -1] -> True
[42, 0, -42] -> True
[42, 81, -81] -> False
[5] -> False
[0] -> True
[-42, 42] -> True

Alternance de parité, version while

On donne une liste L d’entiers et on demande de créer un booléen alterneParite valant True si les éléments de L se suivent en alternant de parité et False sinon. On utilisera une boucle while. Voici des exemples de comportements attendus :

L Alternance de parité
[81, 32, 9, 12] True
[32, 9, 32, 65] True
[32, 9, 31, 82] False
[81] True

Suite croissante d’entiers consécutifs (avec while)

L’exercice doit être codé en utilisant une boucle while.

Écrire un code qui à partir d’une liste \(L\) d’entiers définit une variable booléenne nommée consecutifs qui vaut True si la liste est constituée d’entiers CONSÉCUTIFS croissants et False sinon. Ci-dessous, voici quelques exemples de comportements attendus

[81, 82, 83]       -> True
[82, 81, 83]       -> False
[2020, 2038, 3000] -> False
[81]               -> True

Que des entiers consécutifs

On donne une liste non vide d’entiers L et on demande de déterminer le plus petit indice i de L tels que tous les éléments de L à partir de l’indice i soient des entiers consécutifs. Par exemple, si L est la liste :

L=[34, 35, 10, 25, 40, 42, 43, 44]

alors l’indice attendu est i = 5 car L[i] = 42 et les éléments suivants jusqu’à la fin de la liste sont consécutifs (42, 43, 44) mais cela ne se produit pas avant puisque 40 et 42 ne sont pas consécutifs.

Que des 81 puis que des 12

Soit une liste L non vide formée d’abord d’un certain nombre de fois de l’entier 81 puis d’un certain nombre de fois de l’entier 12. Par exemple, L=[81, 81, 81, 12, 12, 12, 12] ou encore L=[81, 12] ou même L=[12, 12] ainsi que L=[81, 81, 81].

Écrire, à l’aide d’une boucle while, une variable indicePremier_12 qui définit le premier indice du terme de L qui vaut 12. Par exemple, si L = [81, 81, 81, 12, 12, 12, 12] alors indicePremier_12 = 3. Si 12 n’apparaît pas dans L, la variable indicePremier_12 vaudra nn est la longueur de la liste L.

Exemples de comportement :

[81, 81, 81, 12, 12, 12, 12] -> 3
[81, 12] -> 1
[81, 81] -> 2
[12, 12] -> 0

Déclin (boucle while)

On dit qu’une suite d’entiers est une suite en déclin si

  • la suite comporte au moins deux éléments
  • seul le dernier terme de la suite est strictement inférieur au précédent.

Voici trois exemples de suites en déclin :

2 4 5 5 2
4 1
5 5 5 6 6 6 5

En revanche, la suite suivante n’est pas une suite en déclin :

4 4 6 3 5 1

car le terme 3 de la suite est strictement inférieur à son précédent (qui vaut 6) alors que 3 n’est pas le dernier terme de la suite.

De même, la suite suivante n’est pas une suite en déclin :

4 4 6 6

car le dernier terme de la suite n’est pas strictement inférieur à son précédent.

On se donne une liste L. Construire un booléen estEnDeclin qui vaut True si la suite représentée par L est en déclin et False sinon. La liste devra être parcourue avec une boucle while.

Négatif, nul, positif

On donne une liste L d’entiers et on demande d’écrire un booléen neg0pos qui teste si la liste L respecte le motif vérifiant les propriétés suivantes :

  • un entier strictement négatif ne peut être suivi que de 0
  • un entier nul dans la liste ne peut être suivi que d’un entier strictement positif
  • un entier strictement positif dans la liste ne peut être suivi que d’un entier strictement négatif.

Le code devra obligatoirement utiliser une boucle while pertinente.

Exemples de comportement :

[0, 2, -1, 0, 3, -2, 0, 5] -> True
[0, 2, -1, 0, 3, -2, 0] -> True
[0, 2, -1, 0, 3, -2] -> True
[-2, 0, 2, -1, 0, 3, -2, 0, 5] -> True
[1, -1] -> True
[0] -> True
[2, -1, 0, 3, 0, -2, 0, 5] -> False
[0, 2, -1, -4, 0, 3, -2, 0, 5] -> False

Grenouille dans un enclos

Cet exercice est un exercice de dessin. Une grenouille se déplace dans un enclos carré limité par les 4 points \((200, 200)\), \((-200, 200)\), \((-200, -200)\) et \((200, -200)\). Sur le dessin, la grenouille se déplace aléatoirement horizontalement ou verticalement par bond d’une distance aléatoire d’au plus 50 :

../../../_images/tortue_enclos.png

Tracez l’enclos, placez la grenouille au centre et représentez la trajectoire de la grenouille jusqu’à ce qu’elle touche le grillage. Marquez d’un point vert chaque nouvelle position de la grenouille et d’un gros point rouge l’endroit où la grenouille entre en contact avec la clôture.

Zéros en fin de liste

On donne une liste d’entiers et on demande d’écrire un code utilisant une boucle while pertinente et qui détermine le nombre de zéros situés à la fin de la liste. On considérera un indice i initialisé en fin de liste et que l’on fera évoluer. Voici un exemple de comportements :

[3, 5, 0, 0, 0, 0] → 4
[0, 0, 0] → 3
[10, 10] → 0
[42] → 0

Plus long préfixe commun

On donne deux listes L et M d’entiers et on demande de déterminer la sous-liste P qui soit à la fois :

  • commune à L et M,
  • commençant au début de chaque liste,
  • la plus longue possible.

Il est attendu d’utiliser une boucle while. Voici quelques exemples de comportements :

L = [0, 5, 8, 6, 4, 7, 2]
M = [0, 5, 8, 9, 4, 7, 2, 4]
P = [0, 5, 8]
----------------
L = [0, 5, 8, 6, 4, 7, 2]
M = [0, 5, 8, 6, 4, 7, 2, 4]
P = [0, 5, 8, 6, 4, 7, 2]
----------------
L = [0, 5, 8, 6, 4, 7, 2]
M = [1, 5, 8, 6, 4, 7, 2, 4]
P = []
----------------

Eléments absents d’une liste croissante d’entiers

On donne une liste croissante d’entiers L, par exemple

L = [12, 13, 13, 18, 19, 19, 25, 26, 30]

et on demande d’afficher dans l’ordre croissant les entiers absents de la liste L et en indiquant leur rang dans leur ordre d’absence. Avec l’exemple ci-dessus, le programme doit afficher :

14 absent : rang = 1
15 absent : rang = 2
16 absent : rang = 3
17 absent : rang = 4
20 absent : rang = 5
21 absent : rang = 6
22 absent : rang = 7
23 absent : rang = 8
24 absent : rang = 9
27 absent : rang = 10
28 absent : rang = 11
29 absent : rang = 12

Si la liste contient tous les éléments entre son premier et son dernier élément, il ne devra y avoir aucun affichage.

Cette question est inspirée de l’exercice Leetcode : Missing Element in Sorted Array.