Difference between revisions of "FP Laboratory 7"

From Marek Běhálek Wiki
Jump to navigation Jump to search
(Created page with "== List of lists == Consider following type representing picture: <syntaxhighlight lang="Haskell">type Pic = [String]</syntaxhighlight> If you want to print this picture you...")
 
 
(38 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== List of lists ==
+
<translate>
 +
== List of lists == <!--T:11-->
 +
</translate>
 +
 
 +
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/voiTk64SaQM]]</div>
 +
 
 +
<translate>
 +
<!--T:12-->
 
Consider following type representing picture:
 
Consider following type representing picture:
 +
</translate>
  
 
<syntaxhighlight lang="Haskell">type Pic = [String]</syntaxhighlight>
 
<syntaxhighlight lang="Haskell">type Pic = [String]</syntaxhighlight>
  
 +
<translate>
 +
<!--T:13-->
 
If you want to print this picture you can use:
 
If you want to print this picture you can use:
 +
</translate>
  
 
<syntaxhighlight lang="Haskell">
 
<syntaxhighlight lang="Haskell">
Line 11: Line 22:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
<translate>
 +
<!--T:14-->
 
Picture example:  
 
Picture example:  
 +
</translate>
  
 
<syntaxhighlight lang="Haskell">
 
<syntaxhighlight lang="Haskell">
Line 22: Line 36:
 
         "....#....",
 
         "....#....",
 
         "....#####"]
 
         "....#####"]
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="Haskell" class="myDark">
 +
*Main> pp pic
 +
....#....
 +
...###...
 +
..#.#.#..
 +
.#..#..#.
 +
....#....
 +
....#....
 +
....#####
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
<translate>
 +
<!--T:15-->
 
Create functions that:
 
Create functions that:
  
*Flips picture veriticaly and horizontaly.
+
<!--T:16-->
 +
*Flips picture veriticaly and horizontally.
 +
</translate>
 +
 
 
<syntaxhighlight lang="Haskell">
 
<syntaxhighlight lang="Haskell">
 
flipV :: Pic -> Pic
 
flipV :: Pic -> Pic
flipV :: Pic -> Pic</syntaxhighlight>
+
flipH :: Pic -> Pic</syntaxhighlight>
 +
<syntaxhighlight lang="Haskell" class="myDark">
 +
*Main> pp(flipV pic)
 +
....#....
 +
...###...
 +
..#.#.#..
 +
.#..#..#.
 +
....#....
 +
....#....
 +
#####....
 +
*Main> pp(flipH pic)
 +
....#####
 +
....#....
 +
....#....
 +
.#..#..#.
 +
..#.#.#..
 +
...###...
 +
....#....
 +
</syntaxhighlight>
 +
 
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
flipV :: Pic -> Pic
 +
flipV = map reverse
 +
 
 +
flipV' :: Pic -> Pic
 +
flipV' xs = [reverse x|x<-xs]
 +
 
 +
flipH :: Pic -> Pic
 +
flipH = reverse
 +
</syntaxhighlight>
 +
[[File:Tryit.png|center|60px|Try it!|link=https://rextester.com/DQJNA44418]]
 +
</div>
 +
<div style="clear:both"></div>
 +
 
 +
<translate>
 +
<!--T:17-->
 
*Place one picture above another.
 
*Place one picture above another.
 +
</translate>
 +
 
<syntaxhighlight lang="Haskell">above :: Pic -> Pic -> Pic</syntaxhighlight>
 
<syntaxhighlight lang="Haskell">above :: Pic -> Pic -> Pic</syntaxhighlight>
 +
<syntaxhighlight lang="Haskell" class="myDark">
 +
*Main> pp(above pic pic)
 +
....#....
 +
...###...
 +
..#.#.#..
 +
.#..#..#.
 +
....#....
 +
....#....
 +
....#####
 +
....#....
 +
...###...
 +
..#.#.#..
 +
.#..#..#.
 +
....#....
 +
....#....
 +
....#####
 +
</syntaxhighlight>
 +
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
above :: Pic -> Pic -> Pic
 +
above x y = x ++ y
 +
</syntaxhighlight>
 +
[[File:Tryit.png|center|60px|Try it!|link=https://rextester.com/VTCE65032]]
 +
</div>
 +
<div style="clear:both"></div>
 +
 +
<translate>
 +
<!--T:18-->
 
*Place two pictures side by side (consider, that they have the same height).
 
*Place two pictures side by side (consider, that they have the same height).
 +
</translate>
 +
 
<syntaxhighlight lang="Haskell">sideBySide :: Pic -> Pic -> Pic</syntaxhighlight>
 
<syntaxhighlight lang="Haskell">sideBySide :: Pic -> Pic -> Pic</syntaxhighlight>
*Rotate picture to the left and to the right.
+
<syntaxhighlight lang="Haskell" class="myDark">
 +
*Main> pp(sideBySide pic pic)
 +
....#........#....
 +
...###......###...
 +
..#.#.#....#.#.#..
 +
.#..#..#..#..#..#.
 +
....#........#....
 +
....#........#....
 +
....#####....#####
 +
</syntaxhighlight>
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
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 (++)
 +
</syntaxhighlight>
 +
[[File:Tryit.png|center|60px|Try it!|link=https://rextester.com/VTCE65032]]
 +
</div>
 +
<div style="clear:both"></div>
 +
 
 +
<translate>
 +
<!--T:19-->
 +
*Rotate picture to the left and to the right.  
 +
</translate>
 +
 
 +
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/l9qIHTFsEV0]]
 +
</div>
 +
<syntaxhighlight lang="Haskell">
 +
rotateR :: Pic -> Pic
 +
rotateL :: Pic -> Pic
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="Haskell" class="myDark">
 +
*Main> pp(rotateR pic)     
 +
.......
 +
...#...
 +
....#..
 +
.....#.
 +
#######
 +
#....#.
 +
#...#..
 +
#..#...
 +
#......
 +
*Main> pp(rotateL pic)
 +
......#
 +
...#..#
 +
..#...#
 +
.#....#
 +
#######
 +
.#.....
 +
..#....
 +
...#...
 +
.......
 +
</syntaxhighlight>
 +
 
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 
<syntaxhighlight lang="Haskell">
 
<syntaxhighlight lang="Haskell">
 +
toRow :: String -> Pic
 +
toRow xs = map (\x -> [x]) xs -- [[x]|x<-xs]
 +
 
rotateR :: Pic -> Pic
 
rotateR :: Pic -> Pic
rotateL :: Pic -> Pic</syntaxhighlight>
+
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)
 +
</syntaxhighlight>
 +
[[File:Tryit.png|center|60px|Try it!|link=https://rextester.com/JXX12735]]
 +
</div>
 +
<div style="clear:both"></div>
 +
 
 +
<translate>
 +
<!--T:20-->
 
*Increase every point in the picture n times.
 
*Increase every point in the picture n times.
 +
</translate>
 +
 
<syntaxhighlight lang="Haskell">zoom :: Int -> Pic -> Pic</syntaxhighlight>
 
<syntaxhighlight lang="Haskell">zoom :: Int -> Pic -> Pic</syntaxhighlight>
 +
<syntaxhighlight lang="Haskell" class="myDark">
 +
*Main> pp(zoom 2 pic)
 +
........##........
 +
........##........
 +
......######......
 +
......######......
 +
....##..##..##....
 +
....##..##..##....
 +
..##....##....##..
 +
..##....##....##..
 +
........##........
 +
........##........
 +
........##........
 +
........##........
 +
........##########
 +
........##########
 +
</syntaxhighlight>
 +
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
zoom :: Int -> Pic -> Pic
 +
zoom n xs = [concat(map (replicate n) x)|x<-concat (map (replicate n) xs)]
 +
</syntaxhighlight>
 +
[[File:Tryit.png|center|60px|Try it!|link=https://rextester.com/TNVRI28767]]
 +
</div>
 +
<div style="clear:both"></div>
 +
 +
<translate>
 +
== Additional exercises == <!--T:21-->
 +
We will use following additional picture:
 +
</translate>
 +
 +
<syntaxhighlight lang="Haskell">
 +
pic2::Pic
 +
pic2 = [ "#########",
 +
        "#.......#",
 +
        "#.......#",
 +
        "#.......#",
 +
        "#.......#",
 +
        "#.......#",
 +
        "#########"]
 +
</syntaxhighlight>
 +
 +
<translate>
 +
<!--T:22-->
 +
* Create a function that performs the superimposition of two images.
 +
</translate>
 +
<syntaxhighlight lang="Haskell">superimpose :: Pic -> Pic -> Pic</syntaxhighlight>
 +
<syntaxhighlight lang="Haskell" class="myDark">
 +
*Main> pp(superimpose pic pic2)
 +
#########
 +
#..###..#
 +
#.#.#.#.#
 +
##..#..##
 +
#...#...#
 +
#...#...#
 +
#########
 +
</syntaxhighlight>
 +
 +
<translate>
 +
<!--T:23-->
 +
* Create a function that inverts "colors" in a given picture.
 +
</translate>
 +
<syntaxhighlight lang="Haskell">invertColors :: Pic -> Pic</syntaxhighlight>
 +
<syntaxhighlight lang="Haskell" class="myDark">
 +
*Main> pp(invertColors pic)
 +
####.####
 +
###...###
 +
##.#.#.##
 +
#.##.##.#
 +
####.####
 +
####.####
 +
####.....
 +
</syntaxhighlight>
 +
 +
<translate>
 +
<!--T:24-->
 +
* Create a function that for a given integer number n creates a chessboard with dimensions n x n.
 +
</translate>
 +
 +
<syntaxhighlight lang="Haskell">chessBoard :: Int -> Pic</syntaxhighlight>
 +
<syntaxhighlight lang="Haskell" class="myDark">
 +
*Main> pp(chessBoard 5)
 +
#.#.#
 +
.#.#.
 +
#.#.#
 +
.#.#.
 +
#.#.#
 +
*Main> pp(chessBoard 10)
 +
.#.#.#.#.#
 +
#.#.#.#.#.
 +
.#.#.#.#.#
 +
#.#.#.#.#.
 +
.#.#.#.#.#
 +
#.#.#.#.#.
 +
.#.#.#.#.#
 +
#.#.#.#.#.
 +
.#.#.#.#.#
 +
#.#.#.#.#.
 +
</syntaxhighlight>
 +
 +
<translate>
 +
<!--T:25-->
 +
* Define a function makePicture where the list arguments gives the positions of the black points (represented by sharp) and the two integer arguments give the width and height of the picture.
 +
</translate>
 +
<syntaxhighlight lang="Haskell">makePicture :: Int -> Int -> [(Int,Int)]-> Pic</syntaxhighlight>
 +
<syntaxhighlight lang="Haskell" class="myDark">
 +
*Main> pp(makePicture 7 5 [(1,3),(3,2)])
 +
.......
 +
...#...
 +
.......
 +
..#....
 +
.......
 +
</syntaxhighlight>

Latest revision as of 08:56, 26 October 2023

List of lists

Video logo.png

Consider following type representing picture:

type Pic = [String]

If you want to print this picture you can use:

pp :: Pic -> IO ()
pp x = putStr (concat (map (++"\n") x))

Picture example:

pic :: Pic
pic = [ "....#....",
        "...###...",
        "..#.#.#..",
        ".#..#..#.",
        "....#....",
        "....#....",
        "....#####"]
*Main> pp pic
....#....
...###...
..#.#.#..
.#..#..#.
....#....
....#....
....#####

Create functions that:

  • Flips picture veriticaly and horizontally.
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
Try it!
  • Place one picture above another.
above :: Pic -> Pic -> Pic
*Main> pp(above pic pic)
....#....
...###...
..#.#.#..
.#..#..#.
....#....
....#....
....#####
....#....
...###...
..#.#.#..
.#..#..#.
....#....
....#....
....#####
above :: Pic -> Pic -> Pic
above x y = x ++ y
Try it!
  • Place two pictures side by side (consider, that they have the same height).
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 (++)
Try it!
  • Rotate picture to the left and to the right.
Video logo.png
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)
Try it!
  • Increase every point in the picture n times.
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)]
Try it!

Additional exercises

We will use following additional picture:

pic2::Pic
pic2 = [ "#########",
         "#.......#",
         "#.......#",
         "#.......#",
         "#.......#",
         "#.......#",
         "#########"]
  • Create a function that performs the superimposition of two images.
superimpose :: Pic -> Pic -> Pic
*Main> pp(superimpose pic pic2)
#########
#..###..#
#.#.#.#.#
##..#..##
#...#...#
#...#...#
#########
  • Create a function that inverts "colors" in a given picture.
invertColors :: Pic -> Pic
*Main> pp(invertColors pic)
####.####
###...###
##.#.#.##
#.##.##.#
####.####
####.####
####.....
  • Create a function that for a given integer number n creates a chessboard with dimensions n x n.
chessBoard :: Int -> Pic
*Main> pp(chessBoard 5)
#.#.#
.#.#.
#.#.#
.#.#.
#.#.#
*Main> pp(chessBoard 10)
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
  • Define a function makePicture where the list arguments gives the positions of the black points (represented by sharp) and the two integer arguments give the width and height of the picture.
makePicture :: Int -> Int -> [(Int,Int)]-> Pic
*Main> pp(makePicture 7 5 [(1,3),(3,2)])
.......
...#...
.......
..#....
.......