Ciele
- Vyskúšať vyriešenie väčšej úlohy.
Postup
Krok 1: Komplexnejšia úloha
Úloha 1.1
Definujte funkciu, ktorá vykreslí histogram zo zadaného zoznamu prostredníctvom znakov |
. Pričom nech je vykreslená aj legenda — čísla položiek dole a hodnoty naľavo. Pritom nech je v legende vypísaná len každá piata hodnota. Napr. pre zoznam [1,5,3,2,4,1,5,8,7,9,10,6,6,7,5,4,2,2,1]
nech je výsledok:
*Main> putStr (histogram values)
10 |
| |
| | |
| | | | |
| | | | | | |
5 | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | | |
| | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | |
0 5 10 15
values :: [Int]
values = [1,5,3,2,4,1,5,8,7,9,10,6,6,7,5,4,2,2,1]
histogram :: [Int] -> String
histogram = undefined
Riešenie
main :: IO ()
main = putStr (histogram values)
values :: [Int]
values = [1,5,3,2,4,1,5,8,7,9,10,6,6,7,5,4,2,2,1]
histogram :: [Int] -> String
histogram values = unlines ((legendC `above` [" "]) `beside` (body `above` legendL))
where
body = histogramBody values
legendL = [legendLine width]
legendC = legendColumn height
width = length values
height = maximum values
above :: [String] -> [String] -> [String]
above = (++)
beside :: [String] -> [String] -> [String]
beside = zipWith (++)
histogramBody :: [Int] -> [String]
histogramBody values = map (histogramLine values) levels
where levels = reverse [1..maximum values]
histogramLine :: [Int] -> Int -> String
histogramLine values level = concatMap cell values
where cell x | x >= level = " |"
| otherwise = " "
legendLine :: Int -> String
legendLine width = concatMap (rfill 2 . legendLabel) [0..width-1]
legendColumn :: Int -> [String]
legendColumn height = map (rfill 2 . legendLabel) (reverse [1..height])
legendLabel :: Int -> String
legendLabel x | x `mod` 5 == 0 = show x
| otherwise = ""
rfill :: Int -> String -> String
rfill width str = replicate (width - length str) ' ' ++ str
Poznámka
Implementáciu rozdeľte na niekoľko samostatných funkcií, napríklad:
histogramBody :: [Int] -> [String]
legendLine :: Int -> String
legendColumn :: Int -> [String]