FP Cvičení 6
Jump to navigation
Jump to search
Operátory
- Definujte funkce, které provádí příslušné logické operace:
not', and', or', nand', xor', impl', equ'
- Definujte 'standardní' prioritu pro případ, kdy je použijeme jako operátory.
- Implemenetujte funkci která vytiskne pravdivostní tabulku logického výrazu.
table :: (Bool -> Bool -> Bool) -> IO ()
table (\a b -> (and' a (or' a b)))
True True True
True False True
False True False
False False False
not' :: Bool -> Bool
not' True = False
not' False = True
infixl 5 `not'`
and' :: Bool -> Bool -> Bool
and' True True = True
and' _ _ = False
infixl 4 `and'`
or' :: Bool -> Bool -> Bool
or' False False = False
or' _ _ = True
infixl 3 `or'`
nand' :: Bool -> Bool -> Bool
nand' x y = not' (and' x y)
infixl 4 `nand'`
xor' :: Bool -> Bool -> Bool
xor' x y = x/=y
infixl 3 `xor'`
impl' :: Bool -> Bool -> Bool
impl' True False = False
impl' _ _ = True
infixl 2 `impl'`
equ' :: Bool -> Bool -> Bool
equ' x y = x == y
infixl 7 `equ'`
table :: (Bool -> Bool -> Bool) -> IO ()
table expr = putStr (concat [nicePrint [x,y,(expr x y)] |x<-[True,False], y<-[True,False]])
nicePrint :: [Bool] -> String
nicePrint xs = concat [show x++"\t"| x<-xs] ++ "\n"
- Rozšiřte predchozí funkci tak aby přijímala výraz s libovolným počtem proměnných (počet proměnných bude zadán jako druhý parametr).
tablen :: Int -> ([Bool] -> Bool) -> IO ()
tablen 3 (\[a,b,c] -> a `and'` (b `or'` c) `equ'` a `and'` b `or'` a `and'` c)
True True True => True
True True False => True
True False True => True
True False False => False
False True True => False
False True False => False
False False True => False
False False False => False
tablen :: Int -> ([Bool] -> Bool) -> IO ()
tablen n f = putStr(concat [nicePrint x ++ " => " ++ show(f x) ++ "\n" |x<-allValues n]) where
allValues 1 = [[True], [False]]
allValues n = [x:y| x<-[True,False], y<-allValues (n-1)]
nicePrint :: [Bool] -> String
nicePrint xs = concat [show x++"\t"| x<-xs]
Komplexní funkce - Huffmanovo kódování
- Vytvořte funkci která spočíta Huffmanovo kódování pro daný seznam znaků a jejich četností.
huffman :: [(Char, Int)] -> [(Char, String)]
*Main> huffman [('a',45),('b',13),('c',12),('d',16),('e',9),('f',5)]
[('a',"0"),('b',"101"),('c',"100"),('d',"111"),('e',"1101"),('f',"1100")]
import Data.List (sortBy)
huffman :: [(Char, Int)] -> [(Char, String)]
huffman input =
let
prep = [ (y, [(x,"")] ) | (x,y)<-input]
in sortBy (\ (x,_) (y,_) -> compare x y) (step prep) where
step :: [(Int, [(Char, String)])] -> [(Char, String)]
step [(_, result) ] = result
step list = let ((a1, as2):(b1,bs2):rest) = sortBy (\ (x,_) (y,_) -> compare x y) list
in step ((a1+b1, [(x,'0':a2)|(x,a2)<-as2]++[(x,'1':b2)|(x,b2)<-bs2]) : rest)