Kurzusok
/
R
R
/
Feladatok
/
Kevert gyümölcslevek
Kevert gyümölcslevek

Kevert gyümölcslevek

Tanulófeladat

Bevezetés

Alapvetően kétféle ciklus létezik:

  1. Addig ismétlünk, amíg egy feltétel teljesül.
  2. Végigmegyünk egy gyűjtemény elemein.

Mindkettő lehetséges R-ben, bár az első gyakoribb lehet.

while és repeat

Nyitott végű problémákra, ahol előre nem tudjuk, hányszor fut le a ciklus, az R-ben van a feltételes while ciklus, és a feltétel nélküli repeat ciklus (ami ugyanaz, mint a while (TRUE)).

Az alapforma meglehetősen egyszerű:

while (condition) {
  do_something()
}

Ebben az esetben a program addig ismétli a ciklust, amíg a condition már nem TRUE.

Kétféleképpen lehet idő előtt kilépni a ciklusból:

  • A break hatására a ciklus kilép, és a végrehajtás a ciklus záró kapcsos zárójele (}) utáni következő sorban folytatódik.
  • A return(x) leállítja az aktuális függvény végrehajtását, és visszaadja a hívónak az x visszatérési értéket.

Ha ezek a lehetőségek rendelkezésre állnak, néha kényelmes lehet létrehozni egy „végtelen” ciklust a repeat { ... } segítségével, majd a ciklustörzsben keresni egy megállási feltételt, amely kivált egy break vagy return utasítást.

Ez a három változat egyenértékű, és mindegyik x == 0.4444... értékkel végződik.

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
}

Iterálás vektorokon

Ez gyakran szükségtelen R-ben. Ahogy más fogalmaknál is olvashattad, sok függvény egész vektorokon működik.

Előfordulhat azonban, hogy az explicit ciklusok elkerülhetetlenek. Ez különösen akkor igaz, ha:

  • A ciklustörzs mellékhatásokkal jár, például nyomtatás vagy fájl I/O.
  • A ciklus addig folytatódik, amíg el nem ér egy bizonyos kritériumot, kiszámíthatatlan számú iteráció után.

A ciklus feltételét zárójelbe kell tenni. A függvénytestekhez hasonlóan a kapcsos zárójelek elhagyhatók (de gyakran szerepelnek) egysoros ciklustesteknél.

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"

Ha az aktuális iteráció nem teljesít valamilyen feltételt, a next utasítással azonnal átugorhatsz a következő iterációra:

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

Ha szükség van a numerikus indexre, használd a seq_along() függvényt.

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"

Az i in 1:length(v) használata nem ajánlott, mert problémákat okozhat, ha a length(v) nulla. Az 1:0 tartomány megegyezik a c(1, 0) értékkel, így a ciklustörzs lefut, és valószínűleg hibát okoz. A seq_along() függvényt kifejezetten arra tervezték, hogy ezt az esetet helyesen kezelje.

Utasítások

A barátod, Li Mei egy gyümölcslébárt vezet, ahol finom kevert gyümölcsleveket árul. Te gyakori vendég vagy a boltjában, és rájöttél, hogy meg tudnád könnyíteni a barátod életét. Úgy döntesz, hogy a programozási készségeidet bevetve segítesz Li Mei-nak a munkájában.

1. Határozd meg, mennyi ideig tart egy gyümölcslé összekeverése

Li Mei szereti előre megmondani a vendégeinek, mennyit kell várniuk arra a gyümölcslére, amit az étlapról rendeltek. Nehezen jegyzi meg a pontos számokat, mert a gyümölcslevek elkészítési ideje változó. "Pure Strawberry Joy" 0,5 percet vesz igénybe, "Energizer" és "Green Garden" egyenként 1,5 percet, "Tropical Island" 3 percet, "All or Nothing" pedig 5 percet. Minden más ital esetében (például az akciós ajánlatoknál) 2,5 perces elkészítési idővel számolhatsz.

Hogy segíts a barátodnak, írj egy time_to_mix_juice függvényt, amely argumentumként egy étlapon szereplő gyümölcslevet kap, és visszaadja, hány percbe telik az adott ital összekeverése.

time_to_mix_juice("Tropical Island")
# => 3

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

2. Töltsd fel a limecikkészletet

Li Mei sok kreációja tartalmaz limecikket, akár összetevőként, akár a díszítés részeként. Ezért amikor reggel elkezdi a műszakot, meg kell győződnie róla, hogy a limecikkek tárolója tele van a következő napra.

Valósítsd meg a limes_to_cut függvényt, amely megkapja, hány limecikket kell Li Mei-nak felvágni, valamint egy tömböt, amely a keze ügyében lévő egész lime-ok készletét jelöli. Egy "small" lime-ból 6 cikket nyerhet, egy "medium" lime-ból 8 cikket, egy "large" lime-ból pedig 10-et. A lime-okat mindig abban a sorrendben vágja fel, ahogy azok a listában szerepelnek, az első elemmel kezdve. Addig folytatja, amíg el nem éri a szükséges cikkek számát, vagy amíg el nem fogynak a lime-ok.

Li Mei szeretné előre tudni, hány lime-ot kell felvágni. A limes_to_cut függvény adja vissza a felvágandó lime-ok számát.

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

3. Sorold fel a sorban lévő rendelések elkészítési idejét

Li Mei szereti egy monitoron nyomon követni, mennyi ideig tart majd összekeverni azokat a rendeléseket, amelyekre a vendégek várnak.

Valósítsd meg az order_times függvényt, amely megkapja a rendelések sorát, és a stdoutra kiírja, mennyi időbe telik az egyes rendelések elkészítése.

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

Ez a feladat meglehetősen szokatlan az Exercism-ön, mert a stdout-ra való kiírást igényel. Az Exercism feladatainak túlnyomó többsége visszaadott értéket és/vagy valamilyen más mellékhatást vár el.

4. Fejezd be a műszakot

Li Mei mindig délután 3-ig dolgozik. Utána az alkalmazottja, Dmitry veszi át a helyét. Gyakran előfordul, hogy Li Mei műszakjának végén olyan italok vannak, amelyeket megrendeltek, de még nem készítettek el. Dmitry ekkor elkészíti a megmaradt gyümölcsleveket.

Az átadás megkönnyítése érdekében valósítsd meg a remaining_orders függvényt, amely megkapja, hány perc van hátra Li Mei műszakjából, valamint egy tömböt azokból a gyümölcslevekből, amelyeket megrendeltek, de még nem készítettek el. A függvény adja vissza azokat a rendeléseket, amelyeket Li Mei a munkanapja vége előtt már nem tud elkezdeni elkészíteni.

A műszakból hátralévő idő mindig nagyobb lesz, mint 0. Az elkészítendő gyümölcslevek tömbje soha nem lesz üres. Ráadásul a rendeléseket abban a sorrendben készítik el, ahogy azok a tömbben szerepelnek. Ha Li Mei elkezd összekeverni egy italt, mindig be is fejezi, még ha egy kicsit tovább kell is dolgoznia. Ha nem marad olyan rendelés, amivel Dmitrynek foglalkoznia kell, üres vektort kell visszaadni.

remaining_orders(5, c("Energizer", "All or Nothing", "Green Garden"))
# => c("Green Garden")
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
R Exercism

Készen állsz elkezdeni a(z) Kevert gyümölcslevek feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) R nyelvet 21 fogalom111 feladat segítségével, valódi emberi mentorálással, mindez ingyen.