Obchodník

Obchodník Hugo každý den projíždí se svým vozem kolem Eminy farmy a vykupuje úrodu. Jeho ceny se každý den mění. Když má vůz prázdný, platí za každý kus o 2 mince víc než trh. Další den, když je vůz napůl plný, platí o 1 minci víc. Třetí den je vůz plný a Hugo platí jen tolik, kolik trh. Pak všechno odveze do města a začíná se znovu: 2, 1, 0, 2, 1, 0…

Emino pravidlo je jednoduché: když Hugo platí víc než trh, prodá mu všechno ze stodoly. Jinak si úrodu nechá a na konci sezóny ji prodá na trhu.

Hugovy dny jsou úkol pro korutinu, jako v lekci o korutinách: pro funkci, která každý den kousek poběží a zastaví se u coroutine.yield. coroutine.wrap z ní udělá funkci, která ji rozběhne dál: každé zavolání ji nechá běžet do dalšího yield a vrátí hodnotu předanou yield. Třeba co celý den dělá pes Rex:

local function rexuvScenar()
    while true do
        coroutine.yield("hlídá stodolu")
        coroutine.yield("spí u studny")
    end
end

local rex = coroutine.wrap(rexuvScenar)
for den = 1, 3 do
    print("Den " .. den .. ": Rex " .. rex())
end

Vypíše:

Den 1: Rex hlídá stodolu
Den 2: Rex spí u studny
Den 3: Rex hlídá stodolu

Cyklus while true nikdy neskončí, ale tady to nevadí. U každého yield se korutina zastaví a program pokračuje dál. Znovu se rozběhne, až když ji zavoláte, a pokračuje tam, kde přestala, tady uprostřed svého cyklu. Hugův scénář bude stejný, jen v něm bude cyklus for od 2 dolů do 0. Nezapomeňte na jeho krok -1. Bez něj cyklus for neproběhne ani jednou, while true se nikdy nedostane k yield a program poběží, dokud ho web po 5 sekundách nezastaví.

Hugův scénář musí běžet jako korutina, přes coroutine.wrap (nebo coroutine.create a coroutine.resume). Když zavoláte huguvScenar() přímo, korutina to není a yield se nemá kam vrátit: attempt to yield from outside a coroutine (tentokrát bez čísla řádku na začátku). A korutinu vytvořte jen jednou, nad cyklem přes dny. Kdyby vznikala uvnitř cyklu, začínala by každý den od začátku a Hugo by pořád platil o 2 mince víc.

Funkce prodej potřebuje další dva parametry: kdo kupuje (kupec) a o kolik mincí víc než trh platí (priplatek). Dejte jim výchozí hodnoty, jako v lekci o funkcích: kupec = kupec or "Trh" a priplatek = priplatek or 0. Volání prodej(stodola) na konci sezóny pak funguje jako dřív.

prodej musí také vyprázdnit stodolu: stodola[nazev] = nil odebere plodinu, jakmile je prodaná. Bez toho by Hugo stejnou pšenici koupil znovu jiný den, trh ji na konci koupil ještě jednou a Ema by sezónu skončila s 390 mincemi. To je až příliš dobré, než aby to byla pravda. Odebírat klíče stodoly uvnitř cyklu je v pořádku, protože cyklus prochází samostatný seznam ze serazeneNazvy.

První den platí Hugo o 2 mince víc, ale stodola je ještě prázdná a prodej by vypsala Hugo: = 0. Ať tedy vypíše svůj řádek, jen když je celková částka větší než 0.

Pokyny

Pod prodej napište funkci huguvScenar() s cyklem while true, který nikdy neskončí. V něm cyklus for jde od 2 dolů do 0 (s krokem -1) a každé číslo předá coroutine.yield.

Upravte prodej. Dejte jí parametry kupec a priplatek s výchozími hodnotami "Trh" a 0, k ceně každé plodiny přičtěte priplatek, řádek začněte hodnotou kupec místo Trh a každou prodanou plodinu ze stodoly odeberte. Řádek vypište, jen když je celková částka větší než 0. Výstup se zatím nezmění.

V hlavním programu vytvořte nad cyklem přes dny Hugovu korutinu: local hugo = coroutine.wrap(huguvScenar). Každý den po řádku dne zjistěte Hugův příplatek pomocí hugo(). Když je větší než 0, prodejte mu všechno ze stodoly pomocí prodej(stodola, "Hugo", priplatek) a mince přičtěte. Sezóna teď vypadá takto:

Mince: 6
Den 1 (slunečno): mrkev 1/3, pšenice 1/2, dýně 1/6
Den 2 (slunečno): mrkev 2/3, pšenice 2/2, dýně 2/6
Hugo: pšenice 6 x 4 = 24
Den 3 (déšť): mrkev 3/3, pšenice 2/2, dýně 4/6
Den 4 (zataženo): mrkev 1/3, pšenice 1/2, dýně 5/6
Hugo: mrkev 4 x 7, pšenice 6 x 5 = 58
Den 5 (slunečno): mrkev 2/3, pšenice 2/2, dýně 6/6
Hugo: dýně 2 x 21, pšenice 6 x 4 = 66
Den 6 (zataženo): mrkev 3/3, pšenice 1/2, dýně 1/6
Trh: mrkev 4 x 5 = 20
Konec sezóny: 174 mincí

Pokud Hugo platí každý den o 2 mince víc (druhý den pšenice 6 x 5), vytváříte jeho korutinu uvnitř cyklu.

Začněte programovat zdarma

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

6/7