Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mixed juices #277

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@
"booleans"
],
"status": "wip"
},
{
"slug": "mixed-juices",
"name": "Mixed Juices",
"uuid": "c123a64a-e43f-4ecd-85cd-949317606e8d",
"concepts": [
"loops"
],
"prerequisites": [
"switch"
],
"status": "wip"
}
],
"practice": [
Expand Down
1 change: 1 addition & 0 deletions exercises/concept/mixed-juices/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Hints
72 changes: 72 additions & 0 deletions exercises/concept/mixed-juices/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Instructions

Your friend Li Mei runs a juice bar where she sells delicious mixed fruit juices.
You are a frequent customer in her shop and realized you could make your friend's life easier.
You decide to use your coding skills to help Li Mei with her job.

## 1. Determine how long it takes to mix a juice

Li Mei likes to tell her customers in advance how long they have to wait for a juice from the menu that they ordered.
She has a hard time remembering the exact numbers because the time it takes to mix the juices varies.
`"Pure Strawberry Joy"` takes 0.5 minutes, `"Energizer"` and `"Green Garden"` take 1.5 minutes each, `"Tropical Island"` takes 3 minutes and `"All or Nothing"` takes 5 minutes.
For all other drinks (e.g., special offers) you can assume a preparation time of 2.5 minutes.

To help your friend, write a function `time_to_mix_juice` that takes a juice from the menu as an argument and returns the number of minutes it takes to mix that drink.

```R
time_to_mix_juice("Tropical Island")
# => 3

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

## 2. Replenish the lime wedge supply

A lot of Li Mei"s creations include lime wedges, either as an ingredient or as part of the decoration.
So when she starts her shift in the morning she needs to make sure the bin of lime wedges is full for the day ahead.

Implement the function `limes_to_cut` which takes the number of lime wedges Li Mei needs to cut and an array representing the supply of whole limes she has at hand.
She can get 6 wedges from a `"small"` lime, 8 wedges from a `"medium"` lime and 10 from a `"large"` lime.
She always cuts the limes in the order in which they appear in the list, starting with the first item.
She keeps going until she reached the number of wedges that she needs or until she runs out of limes.

Li Mei would like to know in advance how many limes she needs to cut.
The `limes_to_cut` function should return the number of limes to cut.

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

## 3. List the times to mix each order in the queue

Li Mei likes to keep track of how long it will take to mix the orders customers are waiting for.

Implement the `order_times` function, which takes a queue of orders and returns a vector of times to mix.

```R
order_times(c("Energizer", "Tropical Island"))
# => c(1.5, 3.0)
```

## 4. Finish up the shift

Li Mei always works until 3pm.
Then her employee Dmitry takes over.
There are often drinks that have been ordered but are not prepared yet when Li Mei"s shift ends.
Dmitry will then prepare the remaining juices.

To make the hand-over easier, implement a function `remaining_orders` which takes the number of minutes left in Li Mei"s shift and an array of juices that have been ordered but not prepared yet.
The function should return the orders that Li Mei cannot start preparing before the end of her workday.

The time left in the shift will always be greater than 0.
The array of juices to prepare will never be empty.
Furthermore, the orders are prepared in the order in which they appear in the array.
If Li Mei starts to mix a certain juice, she will always finish it even if she has to work a bit longer.
If there are no remaining orders left that Dmitry needs to take care of, an empty vector should be returned.

```R
remaining_orders(5, c("Energizer", "All or Nothing", "Green Garden"))
# => c("Green Garden")
```
61 changes: 61 additions & 0 deletions exercises/concept/mixed-juices/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Introduction

## Iterating over a vector

This is often unnecessary in R.
As discussed in other concepts, many functions will operate on entire vectors.

However, explicit loops are sometimes unavoidable.
This is especially true when the loop body has side effects such as printing or file I/O.

```R
> 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"
```

If the numerical index is needed, use `seq_along()`.

```R
> 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"
```

Using `i in 1:length(v)` is not recommended, as it will cause problems with length-zero vectors.
`seq_along` is designed to handle this case correctly.

## `while` and `repeat`

These work much as you might guess, based on many C-family languages.
If necessary, use `break` to exit a loop completely and `continue` to exit the current iteration.

These three variants are equivalent and all end with `x = 0.4444...`

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

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

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

11 changes: 11 additions & 0 deletions exercises/concept/mixed-juices/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"authors": ["colinleach"],
"contributors": [],
"files": {
"solution": ["mixed-juices.R"],
"test": ["test_mixed-juices.R"],
"exemplar": [".meta/exemplar.R"]
},
"forked_from": ["javascript/mixed-juices"],
"blurb": "Help Li Mei operate her juice store with switch and loops"
}
24 changes: 24 additions & 0 deletions exercises/concept/mixed-juices/.meta/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Design

## Goal

The goal of this exercise is to teach the student the use of `loops` in R, as well as practicing `switch()` learned previously.

## Learning objectives

- Know the ways to iterate over a vector, with a simple `in` and with `seq_along`.
- Know the syntax of `while` and `repeat` loops, including `break` and `continue`.
- Know that loops are less common in R than in most other languages.

## Out of scope

- Avoiding explicit loops with the `apply()` family of functions.

## Concepts

This exercise unlocks no other concepts.

## Prerequisites

- `switch`

51 changes: 51 additions & 0 deletions exercises/concept/mixed-juices/.meta/exemplar.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
time_to_mix_juice <- function(juice) {
switch(juice,
"Pure Strawberry Joy" = 0.5,
"Energizer" = ,
"Green Garden" = 1.5,
"Tropical Island" = 3,
"All or Nothing" = 5,
2.5
)
}

wedges_from_lime <- function(size) {
switch(size,
"small" = 6,
"medium" = 8,
"large" = 10
)
}

# Implementing limes_to_cut() in a vectorized way is possible
# but I found that all the edge cases make the code quite ugly.
limes_to_cut <- function(needed, limes) {
limes_cut <- 0
while (needed > 0 && length(limes) > 0) {
needed <- needed - wedges_from_lime(limes[1])
limes <- limes[-1]
limes_cut <- limes_cut + 1
}
limes_cut
}

# order_times() is contrived and rather unidiomatic, but I don't have
# a better exercise that will work within the test runner.
#
# Students are free to use lapply() if they know about it:
# unlikely at this point in the syllabus.
order_times <- function(orders) {
times <- vector(length = length(orders))
for (i in seq_along(orders)) {
times[i] <- time_to_mix_juice(orders[i])
}
times
}

remaining_orders <- function(time_left, orders) {
while (time_left > 0 && length(orders) > 0) {
time_left <- time_left - time_to_mix_juice(orders[1])
orders <- orders[-1]
}
orders
}
11 changes: 11 additions & 0 deletions exercises/concept/mixed-juices/mixed-juices.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
time_to_mix_juice <- function(juice) {
}

limes_to_cut <- function(needed, limes) {
}

order_times <- function(orders) {
}

remaining_orders <- function(time_left, orders) {
}
Loading