Difference between revisions of "FP Laboratory 10/cs"

From Marek Běhálek Wiki
Jump to navigation Jump to search
(Created page with "* Implementujte abstraktní datový typ [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) <code>Fronta</code>] s následujícími funkcemi:")
 
(Created page with "* Vytvořte implementaci abstraktního datového typu [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) <code>Queue</code>] s následujícími funkcemi:")
 
(22 intermediate revisions by 3 users not shown)
Line 1: Line 1:
== Abstract data types ==
+
== Binární strom ==
 +
* Vytvořte datový typ <code>Tree</code>, který definuje binární strom, kde jsou hodnoty uloženy v listech a také ve větvích.
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
data Tree a = Leaf a
 +
            | Branch a (Tree a) (Tree a) deriving (Show)
 +
</syntaxhighlight>
 +
</div>
 +
<div style="clear:both"></div>
 +
 
 +
* Připravte si příklad binárního stromu.
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
testTree1 :: Tree Int           
 +
testTree1 = Branch 12 (Branch 23 (Leaf 34) (Leaf 45)) (Leaf 55)
 +
 
 +
testTree2 :: Tree Char           
 +
testTree2 = Branch 'a' (Branch 'b' (Leaf 'c') (Leaf 'd')) (Leaf 'e')
 +
</syntaxhighlight>
 +
</div>
 +
<div style="clear:both"></div>
 +
 
 +
* Vytvořte funkci, která sečte všechny hodnoty uložené ve stromu celých čísel.
 +
 
 +
<syntaxhighlight lang="Haskell">
 +
sum' :: Tree Int -> Int
 +
</syntaxhighlight>
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
sum' :: Tree Int -> Int
 +
sum' (Leaf x) = x
 +
sum' (Branch x l r) = sum' l + x + sum' r
 +
</syntaxhighlight>
 +
</div>
 +
<div style="clear:both"></div>
 +
 
 +
* Vytvořte funkci, která extrahuje všechny hodnoty ze stromu do seznamu.
 +
 
 +
<syntaxhighlight lang="Haskell">
 +
toList :: Tree a -> [a]
 +
</syntaxhighlight>
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
toList :: Tree a -> [a]
 +
toList (Leaf x) = [x]
 +
toList (Branch x l r) = toList l ++ [x] ++ toList r
 +
</syntaxhighlight>
 +
</div>
 +
<div style="clear:both"></div>
 +
 
 +
* Vytvořte funkci, která najde maximální hodnotu uloženou ve stromu.
 +
<syntaxhighlight lang="Haskell">
 +
maxTree :: Ord a => Tree a -> a
 +
</syntaxhighlight>
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
maxTree :: Ord a => Tree a -> a
 +
maxTree (Leaf x) = x
 +
maxTree (Branch x l r) = maximum [x, maxTree l, maxTree r]
 +
</syntaxhighlight>
 +
</div>
 +
<div style="clear:both"></div>
 +
 
 +
* Vytvořte funkci, která vrátí maximální hloubku stromu.
 +
<syntaxhighlight lang="Haskell">
 +
depthTree :: Tree a -> Int
 +
</syntaxhighlight>
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
depthTree :: Tree a -> Int
 +
depthTree (Leaf x) = 1
 +
depthTree (Branch x l r) = max (depthTree l) (depthTree r) + 1
 +
</syntaxhighlight>
 +
</div>
 +
<div style="clear:both"></div>
 +
 
 +
* Vytvořte funkci, která vrátí jako seznam ty prvky seznamu, které jsou větší než zadaná hodnota.
 +
<syntaxhighlight lang="Haskell">
 +
getGreaterElements :: Ord a => Tree a -> a -> [a]
 +
</syntaxhighlight>
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
getGreaterElements :: Ord a => Tree a -> a -> [a]
 +
getGreaterElements (Leaf x) y | x > y = [x]
 +
                              | otherwise = []
 +
getGreaterElements (Branch x l r) y | x > y = [x] ++  getGreaterElements l y ++ getGreaterElements r y
 +
                                    | otherwise = getGreaterElements l y ++ getGreaterElements r y
 +
</syntaxhighlight>
 +
</div>
 +
<div style="clear:both"></div>
 +
 
 +
* Jednou z možností, jak reprezentovat strom v textové podobě, je <code>a(b(d,e),c(e,f(g,h)))</code>. Vytvořte funkci, která bude schopna načíst a uložit strom z takového zápisu.
 +
 
 +
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/b0EF9WQw-uw]]</div>
 +
<syntaxhighlight lang="Haskell">
 +
toString :: Show a => Tree a -> String
 +
fromString :: Read a => String -> Tree a
 +
</syntaxhighlight>
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
toString :: Show a => Tree a -> String
 +
toString (Leaf x) = show x
 +
toString (Branch x l r) = show x ++ "(" ++ (toString l) ++ "," ++ (toString r) ++ ")"
 +
 
 +
fromString :: Read a => String -> Tree a
 +
fromString inp = fst (fromString' inp) where
 +
  fromString' :: Read a => String -> (Tree a,String)
 +
  fromString' inp =
 +
    let
 +
      before = takeWhile (\x ->  x /='(' &&  x /=',' &&  x/=')') inp
 +
      after = dropWhile (\x ->  x /='(' &&  x /=',' && x/=')') inp
 +
      value = read before
 +
    in if null after || head after /= '(' then (Leaf value, after) else
 +
        let
 +
          (l,after') = fromString' (tail after)
 +
          (r,after'') = fromString' (tail after')
 +
        in (Branch value l r, tail after'')
 +
</syntaxhighlight>
 +
</div>
 +
<div style="clear:both"></div>
 +
 
 +
== Doplňková cvičení ==
 +
* Vytvořte funkci, která spočítá všechny listy ve stromu.
 +
<syntaxhighlight lang="Haskell">
 +
leafCount :: Tree a -> Int
 +
</syntaxhighlight>
 +
 
 +
* Vytvořte funkci, která spočítá všechny větve stromu.
 +
<syntaxhighlight lang="Haskell">
 +
branchCount :: Tree a -> Int
 +
</syntaxhighlight>
 +
 
 +
* Vytvoření funkce, která zkontroluje, zda je daný prvek uložen ve stromu.
 +
<syntaxhighlight lang="Haskell">
 +
contains :: Eq a => Tree a -> a -> Bool
 +
</syntaxhighlight>
 +
 
 +
* Vytvoření funkce, která vrátí počet prvků větší než zadaná hodnota.
 +
<syntaxhighlight lang="Haskell">
 +
greaterThan :: Ord a => Tree a -> a -> Int
 +
</syntaxhighlight>
 +
 
 +
* Uvažujme následující alternativní definici binárního stromu.
 +
 
 +
<syntaxhighlight lang="Haskell">
 +
data Tree2 a = Null | Branch a (Tree2 a) (Tree2 a)
 +
</syntaxhighlight>
 +
 
 +
* Je tato definice ekvivalentní předchozí definici? Pokud ne, vysvětlete proč a uveďte příklad stromu, který lze zkonstruovat podle první definice, ale ne podle druhé, nebo naopak.
 +
 
 +
* Implementujte všechny výše uvedené funkce upravené pro alternativní definici binárního stromu.
 +
 
 +
== Abstraktní datové typy ==
  
 
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/Stx4YcQbZzg]]</div>  
 
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/Stx4YcQbZzg]]</div>  
  
* Create an implementation of the abstract data type [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) <code>Stack</code>] with following functions:
+
* Vytvořte implementaci abstraktního datového typu [https://en.wikipedia.org/wiki/Stack_(abstract_data_type) <code>Stack</code>] s následujícími funkcemi:
  
 
<syntaxhighlight lang="Haskell">
 
<syntaxhighlight lang="Haskell">
Line 36: Line 196:
 
<div style="clear:both"></div>
 
<div style="clear:both"></div>
  
* Implementujte abstraktní datový typ  [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) <code>Fronta</code>] s následujícími funkcemi:
+
* Vytvořte implementaci abstraktního datového typu [https://en.wikipedia.org/wiki/Queue_(abstract_data_type) <code>Queue</code>] s následujícími funkcemi:
  
 
<syntaxhighlight lang="Haskell">
 
<syntaxhighlight lang="Haskell">
 
isEmpty :: Queue a -> Bool
 
isEmpty :: Queue a -> Bool
 
addQ :: a -> Queue a -> Queue a
 
addQ :: a -> Queue a -> Queue a
remQ :: Queue q -> (a, Queue a)
+
remQ :: Queue a -> (a, Queue a)
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Latest revision as of 10:06, 15 November 2023

Binární strom

  • Vytvořte datový typ Tree, který definuje binární strom, kde jsou hodnoty uloženy v listech a také ve větvích.
data Tree a = Leaf a 
            | Branch a (Tree a) (Tree a) deriving (Show)
  • Připravte si příklad binárního stromu.
testTree1 :: Tree Int            
testTree1 = Branch 12 (Branch 23 (Leaf 34) (Leaf 45)) (Leaf 55)

testTree2 :: Tree Char            
testTree2 = Branch 'a' (Branch 'b' (Leaf 'c') (Leaf 'd')) (Leaf 'e')
  • Vytvořte funkci, která sečte všechny hodnoty uložené ve stromu celých čísel.
sum' :: Tree Int -> Int
sum' :: Tree Int -> Int
sum' (Leaf x) = x
sum' (Branch x l r) = sum' l + x + sum' r
  • Vytvořte funkci, která extrahuje všechny hodnoty ze stromu do seznamu.
toList :: Tree a -> [a]
toList :: Tree a -> [a]
toList (Leaf x) = [x]
toList (Branch x l r) = toList l ++ [x] ++ toList r
  • Vytvořte funkci, která najde maximální hodnotu uloženou ve stromu.
maxTree :: Ord a => Tree a -> a
maxTree :: Ord a => Tree a -> a
maxTree (Leaf x) = x
maxTree (Branch x l r) = maximum [x, maxTree l, maxTree r]
  • Vytvořte funkci, která vrátí maximální hloubku stromu.
depthTree :: Tree a -> Int
depthTree :: Tree a -> Int
depthTree (Leaf x) = 1
depthTree (Branch x l r) = max (depthTree l) (depthTree r) + 1
  • Vytvořte funkci, která vrátí jako seznam ty prvky seznamu, které jsou větší než zadaná hodnota.
getGreaterElements :: Ord a => Tree a -> a -> [a]
getGreaterElements :: Ord a => Tree a -> a -> [a]
getGreaterElements (Leaf x) y | x > y = [x]
                              | otherwise = []
getGreaterElements (Branch x l r) y | x > y = [x] ++  getGreaterElements l y ++ getGreaterElements r y 
                                    | otherwise = getGreaterElements l y ++ getGreaterElements r y
  • Jednou z možností, jak reprezentovat strom v textové podobě, je a(b(d,e),c(e,f(g,h))). Vytvořte funkci, která bude schopna načíst a uložit strom z takového zápisu.
Video logo.png
toString :: Show a => Tree a -> String
fromString :: Read a => String -> Tree a
toString :: Show a => Tree a -> String
toString (Leaf x) = show x
toString (Branch x l r) = show x ++ "(" ++ (toString l) ++ "," ++ (toString r) ++ ")"

fromString :: Read a => String -> Tree a
fromString inp = fst (fromString' inp) where
  fromString' :: Read a => String -> (Tree a,String)
  fromString' inp = 
    let
      before = takeWhile (\x ->  x /='(' &&  x /=',' &&  x/=')') inp 
      after = dropWhile (\x ->  x /='(' &&  x /=',' && x/=')') inp
      value = read before
    in if null after || head after /= '(' then (Leaf value, after) else 
        let
          (l,after') = fromString' (tail after)
          (r,after'') = fromString' (tail after') 
        in (Branch value l r, tail after'')

Doplňková cvičení

  • Vytvořte funkci, která spočítá všechny listy ve stromu.
leafCount :: Tree a -> Int
  • Vytvořte funkci, která spočítá všechny větve stromu.
branchCount :: Tree a -> Int
  • Vytvoření funkce, která zkontroluje, zda je daný prvek uložen ve stromu.
contains :: Eq a => Tree a -> a -> Bool
  • Vytvoření funkce, která vrátí počet prvků větší než zadaná hodnota.
greaterThan :: Ord a => Tree a -> a -> Int
  • Uvažujme následující alternativní definici binárního stromu.
data Tree2 a = Null | Branch a (Tree2 a) (Tree2 a)
  • Je tato definice ekvivalentní předchozí definici? Pokud ne, vysvětlete proč a uveďte příklad stromu, který lze zkonstruovat podle první definice, ale ne podle druhé, nebo naopak.
  • Implementujte všechny výše uvedené funkce upravené pro alternativní definici binárního stromu.

Abstraktní datové typy

Video logo.png
  • Vytvořte implementaci abstraktního datového typu Stack s následujícími funkcemi:
push :: a -> Stack a -> Stack a
pop :: Stack a -> Stack a
top :: Stack a -> a
isEmpty :: Stack a ->Bool
module Stack(Stack, emptyS, push, pop, top, isEmpty) where
  data Stack a = Stack [a] deriving Show

  emptyS :: Stack a
  emptyS = Stack []

  push :: a -> Stack a -> Stack a
  push x (Stack y) = Stack (x:y)
  
  pop :: Stack a -> Stack a
  pop (Stack (_:xs)) = Stack xs

  top :: Stack a -> a
  top (Stack (x:_)) = x

  isEmpty :: Stack a ->Bool
  isEmpty (Stack []) = True
  isEmpty _ = False
  • Vytvořte implementaci abstraktního datového typu Queue s následujícími funkcemi:
isEmpty :: Queue a -> Bool
addQ :: a -> Queue a -> Queue a
remQ :: Queue a -> (a, Queue a)
module Queue(Queue, emptyQ, isEmptyQ, addQ, remQ) where
    data Queue a = Qu [a] deriving Show

    emptyQ :: Queue a
    emptyQ = Qu []
    
    isEmptyQ :: Queue a -> Bool
    isEmptyQ (Qu q) = null q
    
    addQ :: a -> Queue a -> Queue a
    addQ x (Qu xs) = Qu (xs++[x])
    
    remQ :: Queue a -> (a,Queue a)
    remQ q@(Qu xs) | not (isEmptyQ q) = (head xs, Qu (tail xs))
                   | otherwise        = error "remQ"