aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Haskell/LINQuistics.hs231
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