Rekurze a akumulátory (functions are fun, part 2)
Zadáno v pondělí 12. 10.
K odevzdání v pondělí 19. 10.
Získat můžete až 3 bodů
Za úkol je do příštího týdne vypracovat úkol 6b. Zadání je tomto odkazu (tam bude poslední verze se všemi opravami), popřípadě níže.
Doporučuji řešit i další úkoly, například úkoly 6c a úkoly 6d a pro odvážné úkoly 6e a úkoly 6f. Samozřejmě za ty všechny dostanete příslušný počet bodů.
Na co při úkolu myslet
- když pracujeme se seznamy, používáme
cases
- seznamny jsou dvojího druhu, buďto
empty
nebolink(first, rest)
, kdefirst :: T
je první prvek, nějakého typuT
, arest :: List<T>
je zbytek seznamu, a je to tedy seznam cases
umí tyto dva druhy rozpoznat
Zadání
Funkci slice
jsme psali již na hodině, ale zkuste si ji napsat i sami, aniž byste koukali na řešení. U všech funkcí můžete použít jakékoli funkce z lists
(typu take
, drop
, reverse
atp), pokud jste si je již alespoň jednou napsali.
6b3
fun slice<T>(left :: Number, right :: Number, l :: List<T>) -> List<T>: doc: "Returns a list of elements at indices from [left] (inclusive) to [right] (exclusive)," ... where: # Notice that right - left is the length of the resulting list slice(0, 1, [list: "a", "h", "o", "j"]) is [list: "a"] slice(0, 3, [list: "a", "h", "o", "j"]) is [list: "a", "h", "o"] slice(3, 1, [list: 10, 18, 40, 50]) is [list: ] slice(2, 5, [list: 10, 18, 40, 50]) is [list: 40, 50] end
6b4
fun is-palindrome(l :: List<Any>) -> Boolean: doc: "Returns true if [l] is palindrome, false otherwise" l == l where: is-palindrome([list: 1, 2, 3, 2, 1]) is true [list: 1, 2, 3, 2, 1] satisfies is-palindrome [list: "a", "b", "b", "d" ] satisfies lam(s): not(is-palindrome(s)) end [list: "a", "b", "b", "a" ] satisfies is-palindrome string-explode("kobylamamalybok") satisfies is-palindrome string-explode("jelenovipivonelej") satisfies is-palindrome string-explode("jelenovilejjägra") satisfies lam(s): not(is-palindrome(s)) end end
6b5
Tuple /tjůpl/ je k-tice: skupina k-prvků, zde konkrétně používáme tuple velikosti 2 (tedy dvojici). Tuple slouží k "zabalování" více věcí do jedné, většinou v případech, kdy chceme vrátit z funkce více než jednu hodnotu.
Například kdybychom chtěli mít funkci current-position
, která by vracela naši pozici na zeměkouli jako zeměpisnou délku a šířku, vracela by tuple {Number; Number}
(dvě čísla, první odpovídá z.d., druhá z.š.).
Odkazy:
fun list-split-at<T>(i :: Number, l :: List<T>) -> {List<T>; List<T>}: doc: "Return a tuple {x; y} where x are all the elements with indices < [i] and y is the rest of [l]." list-split-at-helper(i, l, empty) where: list-split-at(1, [list: 1, 2, 3]) is {[list: 1]; [list: 2, 3]} list-split-at(3, [list: 1, 2, 3]) is {[list: 1, 2, 3]; [list: ]} list-split-at(0, [list: 1, 2, 3]) is {[list: ]; [list: 1, 2, 3]} end fun list-split-at-helper<T>(i, l, l1 :: List<T>) -> {List<T>; List<T>}: if i == 0: {l1; l} else: cases (List) l: | empty => {l1; empty} # nebo error | link(f, r) => list-split-at-helper(i - 1, r, l1 + [list: f]) end end end
6b6
fun rotate<T>(n :: Number, l :: List<T>) -> List<T>: doc: "Rotate the list by [n] to the right (see the examples)" ... where: rotate(0, [list: 1, 2, 3, 4]) is [list: 1, 2, 3, 4] rotate(1, [list: 1, 2, 3, 4]) is [list: 4, 1, 2, 3] rotate(-2, [list: 1, 2, 3, 4]) is [list: 3, 4, 1, 2] rotate(9, [list: 1, 2, 3, 4]) is [list: 4, 1, 2, 3] end