Difference between revisions of "FP Homework 1/cs"

From Marek Běhálek Wiki
Jump to navigation Jump to search
(Updating to match new version of source page)
Line 10: Line 10:
 
pp x = putStr (concat (map (++"\n") x))
 
pp x = putStr (concat (map (++"\n") x))
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
== Příklad - Lodě==
 +
 +
Napište funkci <code>ships</code>, která má dva argumenty. První je seznam řetězců, které reprezentují hrací plochu jednoho hráče po řádcích postupně shora dolů ('o' - políčko obsazené lodí, ' ' - prázdné pole). Druhým argumentem je seznam dvojic souřadnic políček, na které druhý hráč zkoušel střílet. Vykreslete aktuální stav hry tak, že řádky a sloupce budou označeny svým číslem resp. písmenem, 'o' bude dosud nezasažené políčko s lodí, 'x' zasažené políčko s lodí, '.' místo, kam se střílelo, ale nic nezasáhlo, ' ' prázdná a dosud nezasažená políčka. Můžete předpokládat hrací plochu velikosti 10x10. 
 +
 +
<div style="float: right"> [[File:Video logo.png|80px|link=https://youtu.be/NC6pb3R7A0g]]</div>
 +
<div style="clear:both"></div>
 +
 +
<syntaxhighlight lang="Haskell">
 +
ships :: Result -> [(Char, Int)] -> Result
 +
sampleInput = ["  o    o  ",
 +
              "      ooo ",
 +
              "  oo    ",
 +
              "          ",
 +
              "    o    ",
 +
              "    o    ",
 +
              "    o    ",
 +
              "          ",
 +
              "          ",
 +
              "  oooo    "]
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="Haskell" class="myDark" >
 +
Prelude>pp(ships sampleInput [('a',1),('d',1),('d',2),('c',1),('b',1),('e',1),('f',1),('g',1),('c',7),('c',10)])
 +
10  x    o
 +
  9      ooo
 +
  8  oo
 +
  7  .
 +
  6    o
 +
  5    o
 +
  4    o
 +
  3
 +
  2  .
 +
  1..xxxx.
 +
  abcdefghij
 +
</syntaxhighlight>
 +
<div class="mw-collapsible mw-collapsed" data-collapsetext="Hide solution" data-expandtext="Show solution">
 +
<syntaxhighlight lang="Haskell">
 +
import Data.Char ( ord )
 +
type Result = [String]
 +
 +
pp :: Result -> IO ()
 +
pp x = putStr (concat (map (++"\n") x))
 +
 +
sampleInput :: Result
 +
sampleInput = ["  o    o  ",
 +
              "      ooo ",
 +
              "  oo    ",
 +
              "          ",
 +
              "    o    ",
 +
              "    o    ",
 +
              "    o    ",
 +
              "          ",
 +
              "          ",
 +
              "  oooo    "]
 +
 +
ships :: Result -> [(Char, Int)] -> Result
 +
ships input coordinates = let
 +
    coordinates' = [(ord ch - ord 'a' +1 ,ri) |(ch, ri)<-coordinates]
 +
    get x ch | elem x coordinates' = if ch == 'o' then 'x' else '.'
 +
            | otherwise = ch
 +
    niceShow x = let
 +
        number' = show x
 +
        in if length number' == 1 then "  "++number' else " "++number'       
 +
    nicePrint result = reverse [niceShow number ++ row|(number,row)<-zip [1..] result] ++ ["  abcdefghij"]
 +
    in nicePrint ([[get (ci,ri) ch |(ci,ch)<- zip [1..] row ]| (ri,row)<-zip [1..] (reverse input)])
 +
</syntaxhighlight>
 +
</div>
 +
<div style="clear:both"></div>
 +
 +
 +
 
== 1 - Šachové pozice ==
 
== 1 - Šachové pozice ==
  
Line 108: Line 179:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== 5 - Lodě==
+
== 5 - Turtle ==
 +
Implement a function that will draw the movement of a turtle in a rectangular grid. It will be named <code>draw</code> and it will have one parameter - a list movements. Our turtle can move only horizontally or vertically. Each movement will be described by a pair (its type will be <code>(Char, Int)</code>), where the first character denotates a direction of this movement and the second its length. Possible directions are: <b>l</b>eft, <b>r</b>ight, <b>u</b>p, and <b>d</b>own. As the result, function <code>draw</code> returns a smallest possible rectangle with all turtle's movements. Each block from the grid will be represented with one character. If it was visited by our turtle, then it will be <code>'X'</code>, if it was not, then it will be <code>' '</code>.
  
Napište funkci <code>ships</code>, která má dva argumenty. První je seznam řetězců, které reprezentují hrací plochu jednoho hráče po řádcích postupně shora dolů ('o' - políčko obsazené lodí, ' ' - prázdné pole). Druhým argumentem je seznam dvojic souřadnic políček, na které druhý hráč zkoušel střílet. Vykreslete aktuální stav hry tak, že řádky a sloupce budou označeny svým číslem resp. písmenem, 'o' bude dosud nezasažené políčko s lodí, 'x' zasažené políčko s lodí, '.' místo, kam se střílelo, ale nic nezasáhlo, ' ' prázdná a dosud nezasažená políčka. Můžete předpokládat hrací plochu velikosti 10x10.
 
 
<syntaxhighlight lang="Haskell">
 
<syntaxhighlight lang="Haskell">
ships :: Result -> [(Char, Int)] -> Result
+
draw :: [(Char, Int)] -> Result
sampleInput = ["  o    o  ",
 
              "      ooo ",
 
              "  oo    ",
 
              "          ",
 
              "    o    ",
 
              "    o    ",
 
              "    o    ",
 
              "          ",
 
              "          ",
 
              "  oooo    "]
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 
<syntaxhighlight lang="Haskell" class="myDark" >
 
<syntaxhighlight lang="Haskell" class="myDark" >
Prelude>pp(ships sampleInput [('a',1),('d',1),('d',2),('c',1),('b',1),('e',1),('f',1),('g',1),('c',7),('c',10)])
+
*Main> pp (draw [('u',5),('r',5),('d',5),('l',10),('d',5),('r',5),('u',5)])    
10  x   o
+
    XXXXXX
  9     ooo
+
    X   X
  8  oo
+
     X    X
  7  .
+
    X    X
  6    o
+
    X    X
  5    o
+
XXXXXXXXXXX
  4    o
+
X    X
  3
+
X    X
  2  .
+
X    X
  1..xxxx.
+
X    X
  abcdefghij
+
XXXXXX
 
</syntaxhighlight>
 
</syntaxhighlight>

Revision as of 10:34, 18 November 2020

Základní informace

Ve všech zadáních se očekává výstup na obrazovku. Pro něj je možné použít stejný postup jako ve Cvičení 7.

Definujme si typ pro výstup:

type Result = [String]

Nyní, pokud chceme pěkně vypsat takovýto výstup na obrazovku, můžeme použít:

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

Příklad - Lodě

Napište funkci ships, která má dva argumenty. První je seznam řetězců, které reprezentují hrací plochu jednoho hráče po řádcích postupně shora dolů ('o' - políčko obsazené lodí, ' ' - prázdné pole). Druhým argumentem je seznam dvojic souřadnic políček, na které druhý hráč zkoušel střílet. Vykreslete aktuální stav hry tak, že řádky a sloupce budou označeny svým číslem resp. písmenem, 'o' bude dosud nezasažené políčko s lodí, 'x' zasažené políčko s lodí, '.' místo, kam se střílelo, ale nic nezasáhlo, ' ' prázdná a dosud nezasažená políčka. Můžete předpokládat hrací plochu velikosti 10x10.

Video logo.png
ships :: Result -> [(Char, Int)] -> Result
sampleInput = ["  o    o  ",
               "      ooo ",
               "   oo     ",
               "          ",
               "     o    ",
               "     o    ",
               "     o    ",
               "          ",
               "          ",
               "  oooo    "]
Prelude>pp(ships sampleInput [('a',1),('d',1),('d',2),('c',1),('b',1),('e',1),('f',1),('g',1),('c',7),('c',10)])
 10  x    o
  9      ooo
  8   oo
  7  .
  6     o
  5     o
  4     o
  3
  2   .
  1..xxxx.
   abcdefghij
import Data.Char ( ord ) 
type Result = [String]

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

sampleInput :: Result
sampleInput = ["  o    o  ",
               "      ooo ",
               "   oo     ",
               "          ",
               "     o    ",
               "     o    ",
               "     o    ",
               "          ",
               "          ",
               "  oooo    "]

ships :: Result -> [(Char, Int)] -> Result
ships input coordinates = let
    coordinates' = [(ord ch - ord 'a' +1 ,ri) |(ch, ri)<-coordinates]
    get x ch | elem x coordinates' = if ch == 'o' then 'x' else '.'
             | otherwise = ch
    niceShow x = let 
        number' = show x
        in if length number' == 1 then "  "++number' else " "++number'         
    nicePrint result = reverse [niceShow number ++ row|(number,row)<-zip [1..] result] ++ ["   abcdefghij"]
    in nicePrint ([[get (ci,ri) ch |(ci,ch)<- zip [1..] row ]| (ri,row)<-zip [1..] (reverse input)])


1 - Šachové pozice

Napište funkci chess, která má 2 argumenty typu [String]. Řetězce v seznamech obsahují 3 znaky:

  • první určuje šachovou figuru ('K' - král, 'D' - dáma, 'V' - věž, 'S' - střelec, 'J' - jezdec, 'P' - pěšec)
  • druhý znak určuje sloupec ('a'-'h')
  • třetí je číslo řádku ('1'-'8')

První seznam reprezentuje aktuální rozmístění bílých figur a druhý černých. Vypište aktuální pozici tak, že volná políčka budou reprezentována znakem '.', bílé figury svým písmenem velkým a černé figury svým písmenem malým. Řádky i sloupce budou označeny čísly resp. písmeny.

chess :: [String] -> [String] -> Result
Prelude> pp( chess["Ke1","Ra1","Rh1","Pa2","Be5"] ["Ke8","Ra8","Rh8","Pa7","Qd8","Bc8","Nb8"])
8rnbqk..r
7p.......
6........
5....B...
4........
3........
2P.......
1R...K..R
 abcdefgh

2 - Ticktacktoe

Napište funkci ticktack, která má 2 argumenty. První je dvojice přirozených čísel určující počet sloupců a řádků hrací plochy. Souřadnice jsou počítány z levého dolního rohu. Druhý seznam reprezentuje průběh hry piškvorky, kde jsou souřadnice políček, na které střídavě hrál hráč 'x' a hráč 'o'. Vypište aktuální stav hry tak, že hrací pole bude ohraničeno znaky '-' a '|', volné pozice ' ' a znaky 'x' a 'o' budou na pozicích, kam zahráli příslušní hráči.

ticktack::(Int,Int) -> [(Int,Int)] -> Result
Prelude>pp(ticktack (8,8) [(1,1),(8,8),(2,2),(3,3),(4,2),(3,2)])
----------
|       o|
|        |
|        |
|        |
|        |
|  o     |
| xox    |
|x       |
----------

3 - Bludiště

Napište funkci maze, která má 2 argumenty. Prvním argumentem je seznam řetězců, které reprezentují bludiště po řádcích postupně shora dolů ('*' - stěna, ' ' - průchozí pole, 's' - startovní pozice). Na začátku se nacházíme na pozici 's'. Druhým argumentem je seznam směrů pohybu ('d' - down, 'u' - up, 'l' - left, 'r' - right). Každé písmeno znamená, že se posuneme o 1 buňku daným směrem a na novou pozici umístíme znak '.' Vypište aktuální situaci po provedení všech kroků z druhého seznamu.

maze :: Result -> String -> Result 

sampleInput = ["*********",
               "*s*   * *",
               "* * * * *",
               "* * * * *",
               "*   *   *",
               "******* *",
               "        *",
               "*********"]
Prelude>pp(maze sampleInput "dddrruuurrdddrrddllllll")
*********
*s*...* *
*.*.*.* *
*.*.*.* *
*...*...*
*******.*
 .......*
*********

4 - Hledání min

Napište funkci minesweeper, která má argument typu seznam řetězců. Řetězce reprezentují hrací plochu po řádcích postupně shora dolů ('*' - mina, ' ' - prázdné pole). Vypište hrací pole tak, že miny budou stále reprezentovány '*', ale na každém políčku bez miny bude číslo znamenající celkový počet min, se kterými toto prázdné pole přímo sousedí (sousedit může vodorovně, svisle i šikmo).

minesweeper :: Result -> Result
sampleInput = ["       ",
               " *     ",
               "    *  ",
               "   *   ",
               "      *",
               "***    ",
               "* *    ",
               "***    "]
Prelude>pp(minesweeper sampleInput)
1110000
1*11110
1122*10
001*221
233211*
***2011
*8*3000
***2000

5 - Turtle

Implement a function that will draw the movement of a turtle in a rectangular grid. It will be named draw and it will have one parameter - a list movements. Our turtle can move only horizontally or vertically. Each movement will be described by a pair (its type will be (Char, Int)), where the first character denotates a direction of this movement and the second its length. Possible directions are: left, right, up, and down. As the result, function draw returns a smallest possible rectangle with all turtle's movements. Each block from the grid will be represented with one character. If it was visited by our turtle, then it will be 'X', if it was not, then it will be ' '.

draw :: [(Char, Int)] -> Result
*Main> pp (draw [('u',5),('r',5),('d',5),('l',10),('d',5),('r',5),('u',5)])      
     XXXXXX
     X    X
     X    X
     X    X
     X    X
XXXXXXXXXXX
X    X
X    X
X    X
X    X
XXXXXX