diff options
| author | Syndamia <kamen.d.mladenov@protonmail.com> | 2020-11-15 21:10:18 +0200 |
|---|---|---|
| committer | Syndamia <kamen.d.mladenov@protonmail.com> | 2020-11-15 21:10:18 +0200 |
| commit | 733af501fa0c1adb4a46dd1d3e843cbb8e84f75e (patch) | |
| tree | 0e80d24ecc9969e82797bceea1884be1d574d4f7 /Haskell/LINQuistics.hs | |
| parent | 323eb2455241901c6a588c74663989d49803689f (diff) | |
| download | algorithms-733af501fa0c1adb4a46dd1d3e843cbb8e84f75e.tar algorithms-733af501fa0c1adb4a46dd1d3e843cbb8e84f75e.tar.gz algorithms-733af501fa0c1adb4a46dd1d3e843cbb8e84f75e.zip | |
Added linquistics haskell exercise solution (+ problem explanataion at the bottom of the file)
Diffstat (limited to 'Haskell/LINQuistics.hs')
| -rw-r--r-- | Haskell/LINQuistics.hs | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/Haskell/LINQuistics.hs b/Haskell/LINQuistics.hs new file mode 100644 index 0000000..1ed92de --- /dev/null +++ b/Haskell/LINQuistics.hs @@ -0,0 +1,231 @@ +-- Originally done here: https://github.com/Syndamia/IT-kariera/blob/master/Year%203/Functional%20programming/Exam%20preparation/LINQuistics.hs +-- At the bottom you can find the problem this solves (Note: it was originally made for C# with Linq) + +{- Split -} + +splitAtSection :: String -> Int -> [Int] +splitAtSection str start = if start == length str then [start, 0] + else if str!!start == '.' then [start, 1] + else if str!!start == '(' then [start, 3] + else splitAtSection str (start + 1) + +splitInput :: String -> [String] +splitInput line = if null line then [] + else [take (head (splitAtSection line 0)) line] ++ splitInput (drop (sum (splitAtSection line 0)) line) + +{- Insert -} + +sanitizeArr :: Eq a => [a] -> [a] +sanitizeArr arr = if null arr then [] + else if elem (last arr) (init arr) then sanitizeArr (init arr) + else (sanitizeArr (init arr)) ++ [last arr] + +insertIncl :: [[String]] -> [String] -> [[String]] +insertIncl mat info = if indexOfHead mat (head info) 0 < 0 + then mat ++ [[head info] ++ sanitizeArr (tail info)] + else insertInfo mat (indexOfHead mat (head info) 0) (tail info) + where insertInfo mat index info = take index mat ++ [[head (mat!!index)] ++ sanitizeArr ((tail (mat!!index)) ++ info)] ++ drop (index + 1) mat + +{- Sort -} + +desc :: (Ord a) => [a] -> (a -> a -> Bool) -> (a -> a -> Bool) -> Int -> Int -> [a] +desc arr cond scond end curr = if end == 0 then arr + else if curr == end then desc arr cond scond (end - 1) 0 + else if cond (arr!!curr) (arr!!(curr + 1)) || scond (arr!!curr) (arr!!(curr+1)) + then desc (swapTwo arr curr) cond scond end (curr + 1) + else desc arr cond scond end (curr + 1) + where swapTwo arr i = take i arr ++ [arr!!(i + 1)] ++ [arr!!i] ++ drop (i + 2) arr + +orderByDesc :: (Ord a) => [a] -> (a -> a -> Bool) -> (a -> a -> Bool) -> [a] +orderByDesc arr cond scond = desc arr cond scond (length arr - 1) 0 + +{- Sort conditions -} + +compByUniqCnt :: String -> String -> Bool +compByUniqCnt x y = length x == length y && uniqCnt x < uniqCnt y + where uniqCnt str = length (foldl (\acc x -> if elem x acc then acc else acc ++ [x]) [] str) + +compByLen :: (Ord a) => [a] -> [a] -> Bool +compByLen x y = length x < length y + +compByShort :: (Ord a) => [a] -> [a] -> Bool +compByShort x y = length x > length y + +compByShortestName :: [String] -> [String] -> Bool +compByShortestName x y = length (last (orderByDesc (tail x) compByLen alwaysFalse)) < length (last (orderByDesc (tail y) compByLen alwaysFalse)) + +alwaysFalse :: a -> a -> Bool +alwaysFalse x y = False + +{- Filters -} + +elemsThatContain :: [[String]] -> String -> [[String]] +elemsThatContain mat item = if null mat then [] + else if elem item (head mat) then [head mat] ++ elemsThatContain (tail mat) item + else elemsThatContain (tail mat) item + +getCollWithMostMethods :: [[String]] -> [String] +getCollWithMostMethods mat = mat!!(indexOfMostMethods lengthsArr) + where lengthsArr = map (\x -> length x) mat + indexOfMostMethods arr = foldl (\acc x -> if arr!!x > arr!!acc then x else acc) 0 [1..(length mat - 1)] + +{- Printing -} + +printMethods arr = + if null arr then return () + else do + putStrLn ("* " ++ (head arr)) + printMethods (tail arr) + +printCollection :: [[String]] -> Bool -> IO () +printCollection collection haveMethods = do + if null collection then return () + else do + putStrLn (head (head collection)) + if haveMethods + then printMethods (orderByDesc (tail (head collection)) compByLen alwaysFalse) + else return () + printCollection (tail collection) haveMethods + +{- Main -} + +indexOfHead :: [[String]] -> String -> Int -> Int +indexOfHead mat key start = if null mat then (-1) + else if head (head mat) == key then start + else indexOfHead (tail mat) key (start + 1) + +isNumber :: String -> Bool +isNumber str = if null str then False + else (head str >= '0' && head str <= '9') && ((length str > 1) == isNumber (tail str)) + +readUntilWord :: [[String]] -> IO () +readUntilWord mat = do + line <- getLine + let coll = splitInput line + + if head coll == "exit" then do + final <- getLine + let comm = words final + let collecs = elemsThatContain mat (head comm) + let ordered = orderByDesc collecs compByLen compByShortestName + + printCollection ordered (comm!!1 == "all") + + else if length coll == 1 then do + if isNumber (head coll) then do + let mostMethodsOrd = orderByDesc (tail (getCollWithMostMethods mat)) compByShort alwaysFalse + let n = read (head coll) :: Int + printMethods (take n mostMethodsOrd) + + else if indexOfHead mat (head coll) 0 >= 0 then do + let methods = orderByDesc (tail (mat!!(indexOfHead mat (head coll) 0))) compByLen compByUniqCnt + printMethods methods + + else return() + readUntilWord mat + + else readUntilWord (insertIncl mat coll) + +main :: IO() +main = do + readUntilWord [] + +-- +-- LINQuistics +-- +-- LINQ is the greatest .NET component of all time. You can do almost anything with it. That’s why you have been tasked to do almost everything you can with it. +-- +-- --------- +-- - Input - +-- --------- +-- +-- You will be given several input lines containing information about collections, and LINQ methods that have been called on them, in the following format: +-- +-- {collection}.{method1}().{method2}()....{methodN}() +-- +-- The count of methods may vary. Your task is to store every collection and the methods that have been executed on it. +-- If the collection already exists, you must ADD the new methods to it. Duplicate methods should be REMOVED. +-- +-- ---------- +-- - Output - +-- ---------- +-- +-- If you are given only a collection name, you must print the methods that have been executed on the collection, ordered by their length in descending order. +-- If 2 methods have the same length, order them by the count of unique symbols they have in their names in descending order. +-- +-- Each method must be printed on a new line, with a prefixed asterisk and space (“* ”). +-- +-- If the collection name does NOT exist, you should IGNORE that line of input. +-- +-- If you are given only a digit, you must take the collection which has the most methods, and print the first N methods, with the lowest length (N being the digit given in the input). +-- If there are less than N methods you must print all of them in the same order. +-- +-- NOTE: When printing, you must print only the method name, without its brackets (e.g. “First”, not “First()”). +-- +-- The input sequence ends when you receive the command “exit”. After the ending command, you will receive one last line in the following format: +-- +-- {method} {selection} +-- +-- You must take all collections, which CONTAIN the given method, and print them. The selection will either be “collection” or “all”. +-- If you have “collection”, you must print only the collections’ names in the final output. +-- If you have “all”, you must print the collections and their methods in the following format: +-- +-- {collection} +-- * {method1} +-- * {method2} +-- ... +-- +-- The collections must be printed ordered by the count of their methods in descending order. +-- +-- If 2 collections have the same amount of methods, print the one whose shortest method name is longer than the other one’s shortest method name. +-- +-- The methods must be printed, ordered by their length in descending order. +-- +-- ------------ +-- - Examples - +-- ------------ +-- +-- -- Input ------------------------------- +-- participants.Max().Reverse().ThenBy() +-- participants.OrderBy.Select() +-- participants +-- participants.ToDictionary() +-- collection.Max() +-- collection.Break() +-- exit +-- Max all +-- -- Output ------------------------------ +-- * OrderBy +-- * Reverse +-- * ThenBy +-- * Select +-- * Max +-- participants +-- * ToDictionary +-- * Reverse +-- * OrderBy +-- * ThenBy +-- * Select +-- * Max +-- collection +-- * Break +-- * Max +-- +-- -- Input ------------------------------- +-- elements.Sort() +-- elements.OrderBy() +-- bound +-- elements.Reverse().Select().ThenBy() +-- keys.Reverse().OrderByDescending() +-- keys.Reverse().ThenByDescending() +-- 3 +-- keys.Reverse().OrderBy().ThenBy() +-- values.ToString().ToString().ThenBy() +-- exit +-- Reverse collection +-- -- Output ------------------------------ +-- * Sort +-- * Select +-- * ThenBy +-- keys +-- elements |
