Parcours
/
R
R
/
Exercices
/
Jus mélangés
Jus mélangés

Jus mélangés

Exercice d'apprentissage

Introduction

Il existe essentiellement deux types de boucles :

  1. Boucler jusqu'à ce qu'une condition soit remplie.
  2. Parcourir les éléments d'une collection.

Les deux sont possibles en R, même si la première est sans doute la plus courante.

while et repeat

Pour les problèmes ouverts, où le nombre de tours de boucle n'est pas connu à l'avance, R dispose de la boucle while avec une condition et de la boucle repeat sans condition (équivalente à while (TRUE)).

La forme de base est assez simple :

while (condition) {
  do_something()
}

Dans ce cas, le programme continue de tourner dans la boucle jusqu'à ce que condition ne soit plus TRUE.

Deux façons de quitter la boucle de façon anticipée sont disponibles :

  • Un break fait sortir de la boucle, l'exécution se poursuivant à la ligne suivante après l'accolade fermante } de la boucle.
  • Un return(x) arrête l'exécution de la fonction courante et renvoie la valeur de retour x à l'appelant.

Avec ces options à disposition, il peut parfois être pratique de créer une boucle « infinie » avec repeat { ... }, puis de compter sur une condition d'arrêt trouvée dans le corps de la boucle pour déclencher un break ou un return.

Ces trois variantes sont équivalentes et se terminent toutes avec x == 0.4444...

x <- 12
while (x > 1) {
  x <- x / 3
}

x <- 12
while (TRUE) {
  x <- x/3
  if (x <= 1) break
}

x <- 12
# no boolean clause 
repeat { 
  x <- x/3
  if (x <= 1) break
}

Parcours un vecteur

C'est souvent inutile en R. Comme on l'a vu dans d'autres concepts, de nombreuses fonctions opèrent sur des vecteurs entiers.

Cependant, les boucles explicites sont parfois inévitables. C'est particulièrement vrai lorsque :

  • Le corps de la boucle a des effets de bord, comme l'affichage ou les entrées/sorties de fichiers.
  • La boucle continue jusqu'à ce qu'un critère soit atteint, après un nombre d'itérations imprévisible.

La condition de la boucle doit être entre parenthèses. Comme pour le corps des fonctions, les accolades sont facultatives (mais souvent présentes) pour un corps de boucle tenant sur une seule ligne.

words <- c("This", "is", "a", "loop")
for (w in words) { print(w) } # the braces are optional here
#> [1] "This"
#> [1] "is"
#> [1] "a"
#> [1] "loop"

Si l'itération en cours ne satisfait pas une certaine condition, il est possible de passer immédiatement à l'itération suivante avec un next :

for (n in 1:10) {
    if (is_useless(n)) next
     
    # we decided this iteration could be useful
    do_something_slow(n)
}

Si tu as besoin de l'indice numérique, utilise seq_along().

v <- LETTERS[1:3]
v
#> [1] "A" "B" "C"

for (i in seq_along(v)) { print(sprintf("%s%i", v[i], i)) }
#> [1] "A1"
#> [1] "B2"
#> [1] "C3"

Utiliser i in 1:length(v) n'est pas recommandé, car cela peut poser problème quand length(v) vaut zéro. L'intervalle 1:0 est équivalent à c(1, 0), donc le corps de la boucle s'exécutera et échouera probablement. La fonction seq_along() est conçue pour gérer correctement ce cas.

Instructions

Ton amie Li Mei tient un bar à jus où elle vend de délicieux jus de fruits mélangés. Tu es un client régulier de sa boutique et tu t'es rendu compte que tu pourrais lui faciliter la vie. Tu décides d'utiliser tes compétences en programmation pour aider Li Mei dans son travail.

1. Détermine combien de temps il faut pour mixer un jus

Li Mei aime prévenir ses clients à l'avance du temps qu'ils devront attendre pour le jus qu'ils ont commandé. Elle a du mal à se rappeler les chiffres exacts, car le temps nécessaire pour mixer les jus varie. "Pure Strawberry Joy" prend 0,5 minute, "Energizer" et "Green Garden" prennent 1,5 minute chacun, "Tropical Island" prend 3 minutes et "All or Nothing" prend 5 minutes. Pour toutes les autres boissons (par exemple les offres spéciales), tu peux considérer un temps de préparation de 2,5 minutes.

Pour aider ton amie, écris une fonction time_to_mix_juice qui prend en argument un jus du menu et renvoie le nombre de minutes nécessaires pour mixer cette boisson.

time_to_mix_juice("Tropical Island")
# => 3

time_to_mix_juice("Berries & Lime")
# => 2.5

2. Réapprovisionne la réserve de quartiers de citron vert

Beaucoup des créations de Li Mei contiennent des quartiers de citron vert, que ce soit comme ingrédient ou dans la décoration. Alors, quand elle commence son service le matin, elle doit s'assurer que le bac de quartiers de citron vert est plein pour la journée à venir.

Implémente la fonction limes_to_cut qui prend le nombre de quartiers de citron vert que Li Mei doit couper et un tableau représentant la réserve de citrons verts entiers dont elle dispose. Elle peut obtenir 6 quartiers d'un citron vert "small", 8 quartiers d'un citron vert "medium" et 10 quartiers d'un citron vert "large". Elle coupe toujours les citrons verts dans l'ordre dans lequel ils apparaissent dans la liste, en commençant par le premier élément. Elle continue jusqu'à atteindre le nombre de quartiers dont elle a besoin, ou jusqu'à ce qu'elle n'ait plus de citrons verts.

Li Mei aimerait savoir à l'avance combien de citrons verts elle doit couper. La fonction limes_to_cut doit renvoyer le nombre de citrons verts à couper.

limes_to_cut(25, c("small", "small", "large", "medium", "small"))
# => 4

3. Liste les temps nécessaires pour mixer chaque commande de la file d'attente

Li Mei aime suivre sur un moniteur le temps qu'il faudra pour mixer les commandes des clients qui attendent.

Implémente la fonction order_times, qui prend une file de commandes et affiche sur la sortie standard le temps qu'il faut pour préparer chacune d'elles.

order_times(c("Energizer", "Tropical Island"))
# => 1.5 
# => 3
Note

Cette tâche est assez inhabituelle pour Exercism, car elle nécessite d'écrire sur stdout. La grande majorité des tâches d'exercice sur Exercism attendent une valeur de retour et/ou un autre effet de bord.

4. Termine le service

Li Mei travaille toujours jusqu'à 15 h. Ensuite, son employé Dmitry prend le relais. Il arrive souvent que des boissons aient été commandées mais ne soient pas encore préparées quand le service de Li Mei se termine. Dmitry prépare alors les jus restants.

Pour faciliter la passation, implémente une fonction remaining_orders qui prend le nombre de minutes restantes dans le service de Li Mei et un tableau de jus commandés mais pas encore préparés. La fonction doit renvoyer les commandes que Li Mei ne peut pas commencer à préparer avant la fin de sa journée de travail.

Le temps restant dans le service sera toujours supérieur à 0. Le tableau de jus à préparer ne sera jamais vide. De plus, les commandes sont préparées dans l'ordre dans lequel elles apparaissent dans le tableau. Si Li Mei commence à mixer un certain jus, elle le termine toujours, même si elle doit travailler un peu plus longtemps. S'il ne reste aucune commande dont Dmitry doit s'occuper, un vecteur vide doit être renvoyé.

remaining_orders(5, c("Energizer", "All or Nothing", "Green Garden"))
# => c("Green Garden")
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet
R Exercism

Prêt à commencer Jus mélangés ?

Inscris-toi sur Exercism pour apprendre et maîtriser R avec 21 concepts111 exercices, et un vrai mentorat humain, le tout gratuitement.