FP Cvičení 7
Jump to navigation
Jump to search
Seznamy seznamů
Uvažujte následující typ reprezentující obrázek:
type Pic = [String]
Pro tisk obrázku využijte následující funkci:
pp :: Pic -> IO ()
pp x = putStr (concat (map (++"\n") x))
Příklad obrázku:
pic :: Pic
pic = [ "....#....",
"...###...",
"..#.#.#..",
".#..#..#.",
"....#....",
"....#....",
"....#####"]
*Main> pp pic
....#....
...###...
..#.#.#..
.#..#..#.
....#....
....#....
....#####
Implementujte následující funkce:
- Funkce, která otočí obrázek vertikáně a horizontálně
flipV :: Pic -> Pic
flipH :: Pic -> Pic
*Main> pp(flipV pic)
....#....
...###...
..#.#.#..
.#..#..#.
....#....
....#....
#####....
*Main> pp(flipH pic)
....#####
....#....
....#....
.#..#..#.
..#.#.#..
...###...
....#....
flipV :: Pic -> Pic
flipV = map reverse
flipV' :: Pic -> Pic
flipV' xs = [reverse x|x<-xs]
flipH :: Pic -> Pic
flipH = reverse
- Funkce, která na sebe položi dva obrázky.
above :: Pic -> Pic -> Pic
*Main> pp(above pic pic)
....#....
...###...
..#.#.#..
.#..#..#.
....#....
....#....
....#####
....#....
...###...
..#.#.#..
.#..#..#.
....#....
....#....
....#####
- Funkce, která položí vedle sebe dva obrázky (uvažujte že obrázky mají stejnou výšku).
sideBySide :: Pic -> Pic -> Pic
*Main> pp(sideBySide pic pic)
....#........#....
...###......###...
..#.#.#....#.#.#..
.#..#..#..#..#..#.
....#........#....
....#........#....
....#####....#####
sideBySide :: Pic -> Pic -> Pic
sideBySide xs ys = map (\(x,y) -> x ++ y)(zip xs ys)
sideBySide':: Pic -> Pic -> Pic
sideBySide' (x:xs) (y:ys) = (x ++ y) : sideBySide' xs ys
sideBySide' _ _ = []
sideBySide'' :: Pic -> Pic -> Pic
sideBySide'' = zipWith (++)
- Funkce, která otočí obrázek doprava a doleva.
rotateR :: Pic -> Pic
rotateL :: Pic -> Pic
*Main> pp(rotateR pic)
.......
...#...
....#..
.....#.
#######
#....#.
#...#..
#..#...
#......
*Main> pp(rotateL pic)
......#
...#..#
..#...#
.#....#
#######
.#.....
..#....
...#...
.......
toRow :: String -> Pic
toRow xs = map (\x -> [x]) xs -- [[x]|x<-xs]
rotateR :: Pic -> Pic
rotateR [x] = toRow x
rotateR (x:xs) = (rotateR xs) `sideBySide` (toRow x)
rotateR' :: Pic -> Pic
rotateR' x = foldl1 sideBySide (reverse (map toRow x))
rotateL :: Pic -> Pic
rotateL [x] = reverse(toRow x)
rotateL (x:xs) = reverse(toRow x) `sideBySide` (rotateL xs)
rotateL' :: Pic -> Pic
rotateL' x = foldl1 sideBySide (map (reverse.toRow) x)
- Funkce, která každý bod v obrázku zvětší n-krát.
zoom :: Int -> Pic -> Pic
*Main> pp(zoom 2 pic)
........##........
........##........
......######......
......######......
....##..##..##....
....##..##..##....
..##....##....##..
..##....##....##..
........##........
........##........
........##........
........##........
........##########
........##########
zoom :: Int -> Pic -> Pic
zoom n xs = [concat(map (replicate n) x)|x<-concat (map (replicate n) xs)]
Doplňková cvicení
Vezmeme následující doplňkový obrázek:
pic2::Pic
pic2 = [ "#########",
"#.......#",
"#.......#",
"#.......#",
"#.......#",
"#.......#",
"#########"]
- Vytvorte funkci, která provede superpozici dvou obrázku.
superimpose :: Pic -> Pic -> Pic
*Main> pp(superimpose pic pic2)
#########
#..###..#
#.#.#.#.#
##..#..##
#...#...#
#...#...#
#########
- Vytvorte funkci, která invertuje "barvy" v daném obrázku.
invertColors :: Pic -> Pic
*Main> pp(invertColors pic)
####.####
###...###
##.#.#.##
#.##.##.#
####.####
####.####
####.....
- Vytvořte funkci, která pro zadané celé číslo n vytvoří šachovnici o rozměrech n x n.
chessBoard :: Int -> Pic
*Main> pp(chessBoard 5)
#.#.#
.#.#.
#.#.#
.#.#.
#.#.#
*Main> pp(chessBoard 10)
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
- Definujte funkci
makePicture
, kde argumentem funkce je seznam pozic černých bodů (reprezentovaných znakem'#'
) a dva celočíselné argumenty udávají šírku a výšku obrázku.
makePicture :: Int -> Int -> [(Int,Int)]-> Pic
*Main> pp(makePicture 7 5 [(1,3),(3,2)])
.......
...#...
.......
..#....
.......