Exercices introductifs

Le but de ces petits exercices est d'écrire des programmes simples avec une connaissance minimale du Rust. Faites-les dans l'ordre qui vous amuse. N'hésitez pas à refaire plusieurs fois le même exercice en variant le type de structures de contrôle que vous utilisez par exemple.

Année bissextile

Écrire un programme déterminant si une année est bissextile. Pour savoir si une année est bissextile, il faut que:

  • l'année soit divisible par 4,
  • sauf si elle est divisible par 100,
  • sauf si elle est aussi divisible par 400!

Ainsi, l'année 2001 n'est pas bissextile. En revanche l'année 2000 l'est. Contrairement à l'année 1900 qui ne l'est pas.

  • Objectif : if/else, opérateur %, booléens (bases du Rust).
  • Signature suggérée : fn est_bissextile(annee: u32) -> bool.
  • Cas de test : est_bissextile(2000) -> true, est_bissextile(1900) -> false, est_bissextile(2001) -> false, est_bissextile(2024) -> true.

Nombre d'Armstrong

Un nombre d'Armstrong est un nombre qui est la somme de ses propres chiffres, chacun élevé à la puissance du nombre de chiffres.

Par exemple :

  • \(9\) est un nombre d'Armstrong, car \(9 = 9^1 = 9\),
  • \(10\) n'est pas un nombre d'Armstrong, car \(10 \neq 1^2 + 0^2 = 1\),
  • \(153\) est un nombre d'Armstrong, car : \(153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153\),
  • \(154\) n'est pas un nombre d'Armstrong, car : \(154 \neq 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190\)

Écrivez un programme qui détermine si un nombre est un nombre d'Armstrong.

  • Objectif : décomposition d'un nombre en chiffres (% 10, / 10), boucle, u32::pow (bases du Rust).
  • Signature suggérée : fn est_armstrong(n: u32) -> bool.
  • Cas de test : est_armstrong(9) -> true, est_armstrong(10) -> false, est_armstrong(153) -> true, est_armstrong(154) -> false, est_armstrong(9474) -> true.

Nombres heureux

Un nombre heureux est un entier naturel non nul, qui lorsqu'on calcule la somme des carrés de ses chiffres puis la somme des carrés des chiffres du nombre obtenu et ainsi de suite, on aboutit au nombre 1. Un nombre est malheureux lorsque ce n'est pas le cas.

Ainsi, le nombre 7 est heureux, car:

$$ 7^2=49, $$ $$ 4^2+9^2=97, $$ $$ 9^2+7^2=130, $$ $$ 1^2+3^2+0^2=10, $$ $$ 1^2+0^2=1. $$

D'autres nombres heureux sont 1, 10, 13, 19 par exemple. Il faut faire attention car certains nombres rencontrés dans la suite mènent à une suite périodique: 4, 16, 20, 37, 42, 58, 89, 145 et on ne s'arrête jamais.

Écrivez un programme qui détermine si un nombre est heureux ou malheureux.

  • Objectif : boucle avec condition d'arrêt, détection de cycle (mémoriser les valeurs déjà vues, ou s'arrêter dès qu'on atteint 4), fonctions (bases du Rust).
  • Signature suggérée : fn est_heureux(n: u32) -> bool.
  • Cas de test : est_heureux(7) -> true, est_heureux(1) -> true, est_heureux(19) -> true, est_heureux(2) -> false, est_heureux(4) -> false.

Différence de nombres

Écrivez un programme qui calcule la différence entre le carré de la somme et la somme des carrés des $N$ premiers nombres naturels.

Le carré de la somme des dix premiers entiers naturels est $$ (1 + 2 + ... + 10)^2 = 55^2 = 3025. $$

La somme des carrés des dix premiers nombres naturels est $$ 1^2 + 2^2 + ... + 10^2 = 385. $$

Donc, la différence entre le carré de la somme des dix premiers nombres naturels et la somme des carrés des dix premiers nombres naturels est $$ 3025 - 385 = 2640. $$

  • Objectif : boucle for et accumulateurs, ou itérateurs ((1..=n).sum(), (1..=n).map(|i| i * i).sum()).
  • Signature suggérée : fn difference(n: u32) -> u64.
  • Cas de test : difference(10) -> 2640, difference(1) -> 0, difference(100) -> 25164150.

Nombre premier

Écrire un programme qui détermine si un nombre est premier. Un nombre est premier s'il n'a que deux diviseurs distincts.

  • Objectif : boucle, %, sortie anticipée (return / break) ; optimisation possible : ne tester les diviseurs que jusqu'à la racine carrée de n (bases du Rust).
  • Signature suggérée : fn est_premier(n: u32) -> bool.
  • Cas de test : est_premier(2) -> true, est_premier(1) -> false, est_premier(7) -> true, est_premier(15) -> false, est_premier(97) -> true.

Décomposition en nombres premiers

Écrire un programme qui calcule les facteurs premiers d'un nombre naturel donné.

Exemple d'algorithme

Quels sont les facteurs premiers de 60 ?

  • Notre premier diviseur est 2:
    • 60 est divisible par 2 et il reste 30,
    • 30 est divisible par 2 et il reste 15,
    • 15 n'est pas divisible par 2,
    • 15 est divisible par 3 et il reste 5,
    • 5 n'est pas divisible par 2,
    • 5 n'est pas divisible par 3,
    • 5 n'est pas divisible par 4,
    • 5 est divisible par 5 et il reste 1 et nous avons fini.

Nos diviseurs réussis dans ce calcul représentent la liste des facteurs premiers de 60 : 2, 2, 3 et 5. Si cela vous amuse vous pouvez vérifier qu'ils sont bien premiers en utilisant l'exercice précédent.

  • Objectif : boucle while, %, construction d'un Vec (voir "Les collections") - ou simple affichage au fil de l'eau.
  • Signature suggérée : fn facteurs_premiers(n: u32) -> Vec<u32>.
  • Cas de test : facteurs_premiers(60) -> [2, 2, 3, 5], facteurs_premiers(13) -> [13], facteurs_premiers(1) -> [], facteurs_premiers(360) -> [2, 2, 2, 3, 3, 5].