Advertisement
Tvor0zhok

Лабораторная №3 Haskell

Mar 28th, 2021 (edited)
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.60 KB | None | 0 0
  1. import Data.List
  2. import Data.Maybe
  3. import Data.Char
  4.  
  5. --Задача №1
  6.  
  7. -- №1.1
  8. data Product = Book {bookName :: String, bookAuthor :: String} | Videotape {videotapeName :: String} | CD {cdName :: String, cdSinger :: String, cdAmount :: Int} deriving (Show)
  9.  
  10. -- №1.2
  11. getTitle :: Product -> String
  12. getTitle Book {bookName = name} = name
  13. getTitle Videotape {videotapeName = name} = name
  14. getTitle CD {cdName = name} = name
  15.  
  16. -- №1.3
  17. getTitles :: [Product] -> [String]
  18. getTitles = map getTitle
  19.  
  20. -- №1.4
  21.  
  22. -- Первый способ:
  23. bookAuthors1 :: [Product] -> [String]
  24. bookAuthors1 [] = []
  25. bookAuthors1 (Book {bookAuthor = author} : t) = author : bookAuthors1 t
  26. bookAuthors1 (_ : t) = bookAuthors1 t
  27.  
  28. -- Второй способ:
  29. bookAuthors2 :: [Product] -> [String]
  30. bookAuthors2 = map (\Book {bookAuthor = author} -> author) . filter pr
  31. where pr Book {} = True
  32. pr _ = False
  33.  
  34. -- №1.5
  35. lookupTitle :: String -> [Product] -> Maybe Product
  36. lookupTitle name = find (\p -> getTitle p == name)
  37.  
  38. -- №1.6
  39. lookupTitles :: [String] -> [Product] -> [Product]
  40. lookupTitles names base = mapMaybe (`lookupTitle` base) names
  41.  
  42. -- Задача №2
  43.  
  44. data Suit = Clubs | Diamonds | Hearts | Spades deriving (Eq,Ord,Enum,Show)
  45.  
  46. data Rank = Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King | Ace deriving (Eq,Ord,Enum,Show)
  47.  
  48. data Card = Card {rank :: Rank, suit :: Suit} deriving (Eq,Ord, Show)
  49.  
  50. -- №2.1
  51. isMinor :: Card -> Bool
  52. isMinor Card {rank = r} = not (r == Jack || r == Queen || r == King || r == Ace)
  53.  
  54. -- №2.2
  55. sameSuit :: [Card] -> Bool
  56. sameSuit cards = allClubs || allDiamonds || allHearts || allSpades
  57. where allClubs = all (\Card {suit = s} -> s == Clubs) cards
  58. allDiamonds = all (\Card {suit = s} -> s == Diamonds) cards
  59. allHearts = all (\Card {suit = s} -> s == Hearts) cards
  60. allSpades = all (\Card {suit = s} -> s == Spades) cards
  61.  
  62. -- №2.3
  63. beats :: Card -> Card -> Bool
  64. beats Card {rank = r1, suit = s1} Card {rank = r2, suit = s2} = (s1 == s2) && (value r1 > value r2)
  65. where value r
  66. | r == Two = 2
  67. | r == Three = 3
  68. | r == Four = 4
  69. | r == Five = 5
  70. | r == Six = 6
  71. | r == Seven = 7
  72. | r == Eight = 8
  73. | r == Nine = 9
  74. | r == Ten = 10
  75. | r == Jack = 11
  76. | r == Queen = 12
  77. | r == King = 13
  78. | r == Ace = 14
  79.  
  80. -- №2.4
  81. beats2 :: Card -> Card -> Suit -> Bool
  82. beats2 Card {rank = r1, suit = s1} Card {rank = r2, suit = s2} suit = (s1 == s2 || s1 == suit) && (value2 r1 s1 > value2 r2 s2)
  83. where value2 r s = if s == suit then value r + 14 else value r
  84. value r
  85. | r == Two = 2
  86. | r == Three = 3
  87. | r == Four = 4
  88. | r == Five = 5
  89. | r == Six = 6
  90. | r == Seven = 7
  91. | r == Eight = 8
  92. | r == Nine = 9
  93. | r == Ten = 10
  94. | r == Jack = 11
  95. | r == Queen = 12
  96. | r == King = 13
  97. | r == Ace = 14
  98.  
  99. -- №2.5
  100. beatsList :: [Card] -> Card -> Suit -> [Card]
  101. beatsList cards card suit = filter (\c -> beats2 c card suit) cards
  102.  
  103. -- №2.6
  104. points :: [Card] -> [Int]
  105. points cards = [s + 10*x | x <- [0..k]]
  106. where s = sum $ map value cards
  107. k = sum $ map isAce cards
  108. isAce Card {rank = r} = if r == Ace then 1 else 0
  109. value Card {rank = r}
  110. | r == Ace = 1
  111. | r == Two = 2
  112. | r == Three = 3
  113. | r == Four = 4
  114. | r == Five = 5
  115. | r == Six = 6
  116. | r == Seven = 7
  117. | r == Eight = 8
  118. | r == Nine = 9
  119. | otherwise = 10
  120.  
  121. --Задача №3
  122.  
  123. data Figure = Circle {o :: (Double, Double), r :: Double} | Rectangle {a :: (Double, Double), c :: (Double, Double)} | Triangle {a :: (Double, Double), b :: (Double, Double), c :: (Double, Double)} deriving (Show)
  124.  
  125. -- №3.1
  126. area :: Figure -> Double
  127. area Circle {r = r} = pi * r^2
  128. area Rectangle {a = (xa, ya), c = (xc, yc)} = (xc - xa)*(ya - yc)
  129. area Triangle {a = (xa, ya), b = (xb, yb), c = (xc, yc)} = 0.5 * abs( (xb - xa)*(yc - ya) - (yb - ya)*(xc - xa) )
  130.  
  131. -- №3.2
  132. getRectangles :: [Figure] -> [Figure]
  133. getRectangles = filter pr
  134. where pr Rectangle {} = True
  135. pr _ = False
  136.  
  137. -- №3.3
  138. getBound :: Figure -> Figure
  139. getBound Circle {o = (xo, yo), r = r} = Rectangle (xo - r, yo + r) (xo + r, yo - r)
  140. getBound Rectangle {a = a, c = c} = Rectangle a c
  141. getBound Triangle {a = (xa, ya), b = (xb, yb), c = (xc, yc)} = Rectangle (minimum [xa, xb, xc], maximum [ya, yb, yc]) (maximum [xa, xb, xc], minimum [ya, yb, yc])
  142.  
  143. -- №3.4
  144. getBounds :: [Figure] -> [Figure]
  145. getBounds = map getBound
  146.  
  147. -- №3.5
  148. getFigure :: (Double, Double) -> [Figure] -> Maybe Figure
  149. getFigure (x, y) = find pr
  150. where pr Rectangle {a = (xa, ya), c = (xc, yc)} = xa <= x && x <= xc && yc <= y && y <= ya
  151. pr figure = pr $ getBound figure
  152.  
  153. -- №3.6
  154. move :: Figure -> (Double, Double) -> Figure
  155. move Circle {o = (xo, yo), r = r} (x, y) = Circle {o = (x + xo, y + yo), r = r}
  156. move Rectangle {a = (xa, ya), c = (xc, yc)} (x, y) = Rectangle {a = (x + xa, y + ya), c = (x + xc, y + yc)}
  157. move Triangle {a = (xa, ya), b = (xb, yb), c = (xc, yc)} (x, y) = Triangle {a = (x + xa, y + ya), b = (x + xb, y + yb), c = (x + xc, y + yc)}
  158.  
  159. -- Задача №4
  160.  
  161. data Property = F {f :: Int, s :: Double, n :: Int} | R {f :: Int, n :: Int, sf :: Double, sr :: Double} | H {sh :: Double} deriving(Show)
  162.  
  163. -- №4.1
  164. getHouses :: [(Property, Int)] -> [(Property, Int)]
  165. getHouses = filter pr
  166. where pr (H {}, _) = True
  167. pr _ = False
  168.  
  169. -- №4.2
  170. getByPrice :: Int -> [(Property, Int)] -> [(Property, Int)]
  171. getByPrice price = filter (\(_, cost) -> cost < price)
  172.  
  173. -- №4.3
  174. getByLevel :: Int -> [(Property, Int)] -> [(Property, Int)]
  175. getByLevel fl = filter pr
  176. where pr (F {f = f}, _) = f == fl
  177. pr _ = False
  178.  
  179. -- №4.4
  180. getExceptBounds :: [(Property, Int)] -> [(Property, Int)]
  181. getExceptBounds = filter pr
  182. where pr (F {f = f, n = n}, _) = (f /= 1) && (f /= n)
  183. pr _ = False
  184.  
  185. data Tip = Flat | Room | House deriving(Eq)
  186.  
  187. data Requirement = Requirement {tip :: Tip, smin :: Double, pmax :: Int, floors :: [Int]}
  188.  
  189.  
  190. query :: Requirement -> [(Property, Int)] -> [(Property, Int)]
  191. query Requirement {tip = t, smin = smin, pmax = pmax, floors = floors} =
  192. case t of
  193. Flat -> filter pr1
  194. Room -> filter pr2
  195. House -> filter pr3
  196. where pr1 (F {f = f, s = s, n = n}, cost) = s >= smin && cost <= pmax && elem f floors
  197. pr1 _ = False
  198. pr2 (R {f = f, n = n, sf = sf, sr = sr}, cost) = sr >= smin && cost <= pmax && elem f floors
  199. pr2 _ = False
  200. pr3 (H {sh = sh}, cost) = sh >= smin && cost <= pmax
  201. pr3 _ = False
  202.  
  203. -- Задача №5
  204.  
  205. data Month = January | February | March | April | May | June | July | August | September | October | November | December deriving(Eq, Show)
  206.  
  207. data Edition = Book {author :: String, name :: String} | Magazine {name :: String, month :: Month, year :: Int} | News {name :: String, day :: Int, month :: Month, year :: Int} deriving(Show)
  208.  
  209. -- №5.1
  210. isPeriodic :: Edition -> Bool
  211. isPeriodic Book {} = False
  212. isPeriodic _ = True
  213.  
  214. -- №5.2
  215. getByTytle :: String -> [Edition] -> [Edition]
  216. getByTytle name = filter pr
  217. where pr Book {name = n} = n == name
  218. pr Magazine {name = n} = n == name
  219. pr News {name = n} = n == name
  220.  
  221. -- №5.3
  222. getByMonth :: Month -> Int -> [Edition] -> [Edition]
  223. getByMonth month year = filter pr
  224. where pr Magazine {month = m, year = y} = m == month && y == year
  225. pr News {month = m, year = y} = m == month && y == year
  226. pr _ = False
  227.  
  228. -- №5.4
  229. getByMonths :: [Month] -> Int -> [Edition] -> [Edition]
  230. getByMonths months year = filter pr
  231. where pr Magazine {month = m, year = y} = m `elem` months && y == year
  232. pr News {month = m, year = y} = m `elem` months && y == year
  233. pr _ = False
  234.  
  235. -- №5.5
  236. getAuthors :: [Edition] -> [String]
  237. getAuthors = map (\Book {author = author} -> author) . filter pr
  238. where pr Book {} = True
  239. pr _ = False
  240.  
  241. -- Задача №6
  242.  
  243. data Tip = Integer | Float | String | Struct {members :: [(String, Tip)]} deriving(Eq, Show)
  244.  
  245. newtype Variable = Variable (String, Tip) deriving(Show)
  246.  
  247. -- №6.1
  248. isStructured :: Variable -> Bool
  249. isStructured (Variable (_, Struct {})) = True
  250. isStructured _ = False
  251.  
  252. -- №6.2
  253. getType :: String -> [Variable] -> Maybe Variable
  254. getType name = find pr
  255. where pr (Variable (n, _)) = n == name
  256.  
  257. -- №6.3
  258. getFields :: Variable -> Maybe [(String, Tip)]
  259. getFields (Variable (_, Struct {members = m})) = Just m
  260. getFields _ = Nothing
  261.  
  262. -- №6.4
  263. getByType :: Tip -> [Variable] -> [Variable]
  264. getByType tip = filter pr
  265. where pr (Variable (_, t)) = t == tip
  266.  
  267. -- №6.5
  268. getByTypes :: [Tip] -> [Variable] -> [Variable]
  269. getByTypes tips = filter pr
  270. where pr (Variable (_, t)) = t `elem` tips
  271.  
  272. -- Задача №7
  273.  
  274. data Operation = Delete | DeleteChar {symbol :: Char} | ReplaceChar {sym1 :: Char, sym2 :: Char} | AddChar {symbol :: Char}
  275.  
  276. -- №7.1
  277. process :: Operation -> String -> String
  278. process op s =
  279. case op of
  280. Delete -> []
  281. DeleteChar {symbol = sym} -> filter (/= sym) s
  282. ReplaceChar {sym1 = s1, sym2 = s2} -> map (\sym -> if sym == s1 then s2 else sym) s
  283. AddChar {symbol = sym} -> sym : s
  284.  
  285. -- №7.2
  286. processAll :: String -> [Operation] -> String
  287. processAll = foldl (flip process)
  288.  
  289. -- №7.3
  290. deleteAll :: String -> String -> String
  291. deleteAll s1 s2 = processAll s2 (fun s1)
  292. where fun [] = []
  293. fun (x : xs) = (DeleteChar {symbol = x}) : fun xs
  294.  
  295. -- Задача №8
  296.  
  297. data Note = Birthday {name :: String, day:: Int, month :: String} | Phone {name :: String, number :: String} | Meeting {day :: Int, month :: String, year :: Int, description :: String} deriving(Show)
  298.  
  299. base = [Birthday "Anton" 1 "January", Phone "Petya" "89034557534", Meeting 18 "April" 2021 "Olimpiada SGU", Phone "Anton" "89334556776"]
  300.  
  301. -- №8.1
  302. getByName :: String -> [Note] -> (String, (Int, String))
  303. getByName name notes = fun $ filter pr notes
  304. where fun [Birthday {name = name, day = d, month = m}, Phone {name = n, number = num}] = (num, (d, m))
  305. fun [Phone {name = n, number = num}, Birthday {name = name, day = d, month = m}] = (num, (d, m))
  306. fun _ = error "There are no inf about his birthday or his phone"
  307. pr Birthday {name = n} = n == name
  308. pr Phone {name = n} = n == name
  309. pr _ = False
  310.  
  311. -- №8.2
  312. getByLetter :: Char -> [Note] -> [String]
  313. getByLetter l = nub . map fun . filter pr
  314. where fun Birthday {name = n} = n
  315. fun Phone {name = n} = n
  316. pr Birthday {name = n} = head n == l
  317. pr Phone {name = n} = head n == l
  318. pr _ = False
  319.  
  320. -- №8.3
  321. getAssignment :: Int -> String -> Int -> [Note] -> [String]
  322. getAssignment d m y notes = phones `union` meets
  323. where phones = map f1 $ filter p1 notes
  324. f1 Phone {number = num} = num
  325. p1 Phone {name = n, number = num} = n `elem` names
  326. p1 _ = False
  327. names = map f2 $ filter p2 notes
  328. f2 Birthday {name = n} = n
  329. p2 Birthday {day = day, month = month} = (day == d) && (month == m)
  330. p2 _ = False
  331. meets = map f3 $ filter p3 notes
  332. f3 Meeting {description = d} = d
  333. p3 Meeting {day = day, month = month, year = year} = (day == d) && (month == m) && (year == y)
  334. p3 _ = False
  335.  
  336. -- Задача №9
  337.  
  338. data Keystroke = Symbol Char | Shift Char | CapsLock deriving(Show)
  339.  
  340. -- №9.1
  341. getAlNum :: [Keystroke] -> [Keystroke]
  342. getAlNum = filter pr
  343. where pr CapsLock = False
  344. pr _ = True
  345.  
  346. -- №9.2
  347. getRaw :: [Keystroke] -> String
  348. getRaw = map fun . getAlNum
  349. where fun (Symbol c) = c
  350. fun (Shift c) = c
  351.  
  352. -- №9.3
  353. isCapsLocked :: [Keystroke] -> Bool
  354. isCapsLocked keystrokes = sum (map fun keystrokes) `mod` 2 == 1
  355. where fun CapsLock = 1
  356. fun _ = 0
  357.  
  358. -- №9.4
  359. getString :: [Keystroke] -> String
  360. getString = helper False
  361. where helper pr [] = []
  362. helper pr (CapsLock : ks) = helper (not pr) ks
  363. helper pr (k : ks) = getSymbol pr k : helper pr ks
  364. getSymbol pr (Symbol c) = if pr then toUpper c else c
  365. getSymbol pr (Shift c) = if isAlpha c then if pr then c else toUpper c else shiftNum c
  366. shiftNum c =
  367. case c of
  368. '1' -> '!'
  369. '2' -> '@'
  370. '3' -> '#'
  371. '4' -> '$'
  372. '5' -> '%'
  373. '6' -> '^'
  374. '7' -> '&'
  375. '8' -> '*'
  376. '9' -> '('
  377. '0' -> ')'
  378.  
  379. -- Задача №10
  380.  
  381. data T = Lab {subject :: String, number :: Int} | CGT {subject :: String} | Referat {subject :: String, topic :: String} deriving(Show)
  382.  
  383. newtype Task = Task (T, Maybe Int) deriving(Show)
  384.  
  385. curriculum = [Task (Lab "Haskell" 2, Just 10), Task (Referat "Haskell" "IO", Nothing), Task (CGT "Haskell", Nothing), Task (Lab "Haskell" 1, Just 5), Task (Lab "Haskell" 1, Just 1), Task (Lab "Net" 3, Nothing), Task (Referat "Net" "Cisco", Just 5), Task (Lab "Net" 4, Just 10)]
  386.  
  387. -- №10.1
  388. getByTytle :: String -> [Task] -> [Task]
  389. getByTytle sub = filter pr
  390. where pr (Task (t, _)) =
  391. case t of
  392. Lab {subject = s} -> s == sub
  393. CGT {subject = s} -> s == sub
  394. Referat {subject = s} -> s == sub
  395.  
  396. -- №10.2
  397. getReferats :: [Task] -> [String]
  398. getReferats = map (\(Task (Referat {topic = t}, _)) -> t) . filter pr
  399. where pr (Task (Referat {}, _)) = True
  400. pr _ = False
  401.  
  402. -- №10.3
  403. getRest :: [Task] -> [Task]
  404. getRest = filter pr
  405. where pr (Task (_, Nothing)) = True
  406. pr _ = False
  407.  
  408. -- №10.4
  409. getRestForWeek :: Int -> [Task] -> [Task]
  410. getRestForWeek week = filter pr
  411. where pr (Task (_, Nothing)) = True
  412. pr (Task (_, Just w)) = w > week
  413.  
  414. -- №10.5
  415. getPlot :: [Task] -> [(Int, Int)]
  416. getPlot tasks = [(w, getTasksForWeek w tasks) | w <- weeks]
  417. where weeks = nub $ map fun1 $ filter pr tasks
  418. fun1 (Task (_, Just a)) = a
  419. pr (Task (_, Just a)) = True
  420. pr _ = False
  421. getTasksForWeek week tasks = sum $ map (`fun2` week) tasks
  422. fun2 (Task (_, Just a)) week = if a == week then 1 else 0
  423. fun2 _ _ = 0
  424.  
  425. http://learnyouahaskell.com
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement