mirror of
https://github.com/robonen/fp-haskell.git
synced 2026-03-20 10:54:40 +00:00
Initial commit
This commit is contained in:
17
src/1a/1a.hs
Normal file
17
src/1a/1a.hs
Normal file
@@ -0,0 +1,17 @@
|
||||
-- На вход функции подается два числовых списка [a1, a2, …,an]
|
||||
-- и [b1, b2, …, bn]. Функция должна формировать новый
|
||||
-- список [min(a1,b1), min(a2,b2), …, min(an,bn)].
|
||||
|
||||
mmin :: Ord a => a -> a -> a
|
||||
mmin x y = if x < y then x else y
|
||||
|
||||
minList :: [Int] -> [Int] -> [Int]
|
||||
minList [] _ = []
|
||||
minList _ [] = []
|
||||
minList (x:xs) (y:ys) = mmin x y : minList xs ys
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
let a = [0, 5, 10, 3]
|
||||
let b = [5, 1, 3]
|
||||
print $ minList a b
|
||||
18
src/1b/1b.hs
Normal file
18
src/1b/1b.hs
Normal file
@@ -0,0 +1,18 @@
|
||||
-- Напишите функцию, зависящую от двух аргументов x и y,
|
||||
-- удаляющую все вхождения x в список y. Х может быть атомом или списком.
|
||||
|
||||
removeElem :: Eq a => a -> [a] -> [a]
|
||||
removeElem _ [] = []
|
||||
removeElem y (x:xs)
|
||||
| x == y = removeElem y xs
|
||||
| otherwise = x : removeElem y xs
|
||||
|
||||
removeAll :: Eq a => [a] -> [a] -> [a]
|
||||
removeAll [] x = x
|
||||
removeAll (y:ys) x = removeAll ys (removeElem y x)
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
let x = [1, 2, 3, 4, 5, 6, 7]
|
||||
print $ removeAll [3] x
|
||||
print $ removeAll [2, 5] x
|
||||
12
src/2a/2a.hs
Normal file
12
src/2a/2a.hs
Normal file
@@ -0,0 +1,12 @@
|
||||
-- Напишите функцию (f s n), которая из двухуровневого
|
||||
-- списка чисел s создает новый одноуровневый список квадратов
|
||||
-- чисел, исключив все элементы исходного списка s, которые
|
||||
-- меньше заданного числа n.
|
||||
|
||||
f :: [[Int]] -> Int -> [Int]
|
||||
f s n = [x*x | xs <- s, x <- xs, x >= n]
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
let s = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
||||
print $ f s 5
|
||||
12
src/2b/2b.hs
Normal file
12
src/2b/2b.hs
Normal file
@@ -0,0 +1,12 @@
|
||||
-- Определите функцию (f a n), которая от двух числовых
|
||||
-- аргументов строит следующий список:
|
||||
-- [a, a*(a+1),a*(a+1)*(a+2),…,a*(a+1)*(a+2)*…*(a+n)].
|
||||
|
||||
f :: Int -> Int -> [Int]
|
||||
f a n = scanl (*) a $ take n [a+1..]
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
let a = 2
|
||||
let n = 5
|
||||
print $ f a n
|
||||
62
src/3/3.hs
Normal file
62
src/3/3.hs
Normal file
@@ -0,0 +1,62 @@
|
||||
-- Определите тип данных для хранения следующей информации по
|
||||
-- футбольным командам: название команды; информация по
|
||||
-- результатам сыгранных игр – [(x1,y1), (x2,y2), …], где каждый
|
||||
-- кортеж – это информация по отдельной игре и xi – количество
|
||||
-- забитых голов, yi – количество пропущенных голов. Определить
|
||||
-- для этого типа функцию сравнения ‘==’ класса Eq, а также функции
|
||||
-- ‘<’, ‘<=’ класса Ord, сравнивая команды по количеству набранных
|
||||
-- очков (выигрыш=3, ничья=1), если у двух команд равное
|
||||
-- количество набранных очков, то дальше сравнивают разницу между
|
||||
-- количеством забитых и количеством пропущенных голов.
|
||||
|
||||
import Data.List (sortBy)
|
||||
|
||||
data FootballTeam = FootballTeam {
|
||||
teamName :: String,
|
||||
gameResults :: [(Int, Int)]
|
||||
} deriving (Show)
|
||||
|
||||
instance Eq FootballTeam where
|
||||
team1 == team2 = team1Score == team2Score && team1Diff == team2Diff
|
||||
where
|
||||
team1Score = calculateScore team1
|
||||
team2Score = calculateScore team2
|
||||
team1Diff = calculateGoalDifference team1
|
||||
team2Diff = calculateGoalDifference team2
|
||||
|
||||
instance Ord FootballTeam where
|
||||
compare team1 team2
|
||||
| team1Score < team2Score = LT
|
||||
| team1Score > team2Score = GT
|
||||
| team1Diff < team2Diff = LT
|
||||
| team1Diff > team2Diff = GT
|
||||
| otherwise = EQ
|
||||
where
|
||||
team1Score = calculateScore team1
|
||||
team2Score = calculateScore team2
|
||||
team1Diff = calculateGoalDifference team1
|
||||
team2Diff = calculateGoalDifference team2
|
||||
|
||||
calculateScore :: FootballTeam -> Int
|
||||
calculateScore team = sum [3 | (x, y) <- gameResults team, x > y] + sum [1 | (x, y) <- gameResults team, x == y]
|
||||
|
||||
calculateGoalDifference :: FootballTeam -> Int
|
||||
calculateGoalDifference team = sum [x - y | (x, y) <- gameResults team]
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
let teams = [FootballTeam "Team1" [(2, 1), (1, 1), (0, 1)], -- score: 4, diff: 0
|
||||
FootballTeam "Team2" [(1, 2), (3, 1), (2, 2)], -- score: 4, diff: 1
|
||||
FootballTeam "Team3" [(1, 1), (2, 2), (3, 3)]] -- score: 3, diff: 0
|
||||
|
||||
putStr "Sorted teams: "
|
||||
print $ map teamName $ sortBy compare teams
|
||||
|
||||
let team1 = FootballTeam "Team1" [(2, 1), (1, 1), (0, 1)] -- score: 4, diff: 0
|
||||
let team2 = FootballTeam "Team2" [(2, 1), (1, 1), (0, 1)] -- score: 4, diff: 0
|
||||
let team3 = FootballTeam "Team3" [(2, 1), (2, 1), (0, 1)] -- score: 4, diff: 1
|
||||
|
||||
putStr "Equal team1 and team2: "
|
||||
print $ team1 == team2
|
||||
putStr "Equal team1 and team3: "
|
||||
print $ team1 == team3
|
||||
68
src/4/4.hs
Normal file
68
src/4/4.hs
Normal file
@@ -0,0 +1,68 @@
|
||||
-- В файлах хранится информация об актерах и фильмах в следующем
|
||||
-- виде: актер(<фамилия>,<название_фильма>),
|
||||
-- фильм(<название_фильма>,<жанр>,<год_выпуска>). Написать
|
||||
-- программу, формирующую список актеров по жанрам (если актер
|
||||
-- снимался в фильмах разных жанров, то определять его жанр исходя
|
||||
-- из максимального количества ролей в фильмах одного жанра).
|
||||
|
||||
import Text.Regex.Posix
|
||||
import Data.List (nubBy, maximumBy, group, sort)
|
||||
import Data.Ord (comparing)
|
||||
import System.Directory (getCurrentDirectory)
|
||||
|
||||
data Actor = Actor {
|
||||
name :: String,
|
||||
movieTitle :: String
|
||||
} deriving (Show)
|
||||
|
||||
data Movie = Movie {
|
||||
title :: String,
|
||||
genre :: String,
|
||||
year :: String
|
||||
} deriving (Show)
|
||||
|
||||
--parseActorsTest :: String -> [[String]]
|
||||
--parseActorsTest content = content =~ actorRegex :: [[String]]
|
||||
-- where actorRegex = "actor\\(([^,]+),([^\\)]+)\\)"
|
||||
|
||||
parseActors :: String -> [Actor]
|
||||
parseActors content = map (\x -> Actor (x !! 1) (x !! 2)) (content =~ actorRegex :: [[String]])
|
||||
where actorRegex = "actor\\(([^,]+),([^\\)]+)\\)"
|
||||
|
||||
parseMovies :: String -> [Movie]
|
||||
parseMovies content = map (\x -> Movie (x !! 1) (x !! 2) (x !! 3)) (content =~ movieRegex :: [[String]])
|
||||
where movieRegex = "movie\\(([^,]+),([^,]+),([^\\)]+)\\)"
|
||||
|
||||
actorsWithMoviesTitle :: [Actor] -> [(Actor, [String])]
|
||||
actorsWithMoviesTitle actors =
|
||||
[(actor, [title | movie <- movies, let title = movieTitle movie]) |
|
||||
actor <- uniqueActors,
|
||||
let movies = filter (\movie -> name actor == name movie) actors]
|
||||
where uniqueActors = nubBy (\x y -> name x == name y) actors
|
||||
|
||||
joinMoviesWithActors :: [Movie] -> [(Actor, [String])] -> [(Actor, [Movie])]
|
||||
joinMoviesWithActors movies actors =
|
||||
[(actor, [movie | movie <- movies, title movie `elem` movieTitles]) | (actor, movieTitles) <- actors]
|
||||
|
||||
mostCommonGenre :: [Movie] -> String
|
||||
mostCommonGenre = head . maximumBy (comparing length) . group . sort . map genre
|
||||
|
||||
mostPopularGenreByActor :: [(Actor, [Movie])] -> [(Actor, String)]
|
||||
mostPopularGenreByActor = map (\(a, ms) -> (a, mostCommonGenre ms))
|
||||
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
|
||||
content <- readFile "src/4/data.txt"
|
||||
|
||||
-- print $ parseActorsTest content
|
||||
|
||||
let actors = parseActors content
|
||||
movies = parseMovies content
|
||||
acWithMovieTitles = actorsWithMoviesTitle actors
|
||||
acWithMovies = joinMoviesWithActors movies acWithMovieTitles
|
||||
mostPopularGenre = mostPopularGenreByActor acWithMovies
|
||||
|
||||
putStrLn "Most popular genre by actor:"
|
||||
mapM_ (\x -> putStrLn $ name (fst x) ++ " - " ++ snd x) mostPopularGenre
|
||||
47
src/4/4.old.hs
Normal file
47
src/4/4.old.hs
Normal file
@@ -0,0 +1,47 @@
|
||||
import Text.Regex.Posix
|
||||
import Data.List (nubBy, maximumBy, group, sort)
|
||||
import Data.Ord (comparing)
|
||||
|
||||
data Actor = Actor {
|
||||
name :: String,
|
||||
movieTitle :: String
|
||||
} deriving (Show)
|
||||
|
||||
data Movie = Movie {
|
||||
title :: String,
|
||||
genre :: String,
|
||||
year :: String
|
||||
} deriving (Show)
|
||||
|
||||
parseActors :: String -> [Actor]
|
||||
parseActors content = map (\x -> Actor (x !! 1) (x !! 2)) (content =~ actorRegex :: [[String]])
|
||||
where actorRegex = "actor\\(([^,]+),([^\\)]+)\\)"
|
||||
|
||||
parseMovies :: String -> [Movie]
|
||||
parseMovies content = map (\x -> Movie (x !! 1) (x !! 2) (x !! 3)) (content =~ movieRegex :: [[String]])
|
||||
where movieRegex = "movie\\(([^,]+),([^,]+),([^\\)]+)\\)"
|
||||
|
||||
actorsWithMoviesTitle :: [Actor] -> [(Actor, [String])]
|
||||
actorsWithMoviesTitle actors = uniqueActors
|
||||
where uniqueActors = nubBy (\x y -> name (fst x) == name (fst y)) actorsWithMovies
|
||||
actorsWithMovies = map (\x -> (x, map movieTitle (filter (\y -> name x == name y) actors))) actors
|
||||
|
||||
joinMoviesWithActors :: [Movie] -> [(Actor, [String])] -> [(Actor, [Movie])]
|
||||
joinMoviesWithActors movies actors = map (\x -> (fst x, map (\y -> head (filter (\z -> title z == y) movies)) (snd x))) actors
|
||||
|
||||
mostPopularGenreByActor :: [(Actor, [Movie])] -> [(Actor, String)]
|
||||
mostPopularGenreByActor actorsWithMovies = map (\x -> (fst x, mostCommonGenre (snd x))) actorsWithMovies
|
||||
where mostCommonGenre movies = head $ maximumBy (\x y -> compare (length x) (length y)) $ group $ sort $ map genre movies
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
content <- readFile "data.txt"
|
||||
|
||||
let actors = parseActors content
|
||||
movies = parseMovies content
|
||||
ac = actorsWithMoviesTitle actors
|
||||
acWithMovies = joinMoviesWithActors movies ac
|
||||
mostPopularGenre = mostPopularGenreByActor acWithMovies
|
||||
|
||||
putStrLn "Most popular genre by actor:"
|
||||
mapM_ (\x -> putStrLn $ name (fst x) ++ " - " ++ snd x) mostPopularGenre
|
||||
11
src/4/data.txt
Normal file
11
src/4/data.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
actor(ivanov,movie1)
|
||||
actor(ivanov,movie2)
|
||||
actor(ivanov,movie3)
|
||||
actor(petrov,movie4)
|
||||
actor(sidrov,movie1)
|
||||
|
||||
movie(movie1,action,2000)
|
||||
movie(movie2,comedy,2005)
|
||||
movie(movie3,action,2010)
|
||||
movie(movie4,drama,2020)
|
||||
movie(movie5,action,2021)
|
||||
Reference in New Issue
Block a user