Skip to content

Instantly share code, notes, and snippets.

@mather
Last active April 27, 2016 00:26
Show Gist options
  • Select an option

  • Save mather/773d557e96b921592412 to your computer and use it in GitHub Desktop.

Select an option

Save mather/773d557e96b921592412 to your computer and use it in GitHub Desktop.
複数のアプローチでリスト内の同一要素の数を数える
module ElemCount where
import Data.List
-- | for empty list
--
-- >>> elemCountOrd []
-- []
--
-- | count the same element
--
-- >>> elemCountOrd [1,1,1,2,2,3,1,2,3]
-- [(1,4),(2,3),(3,2)]
--
-- | target list is sorted before counting
--
-- >>> elemCountOrd [1,1,1,3,1,2,3]
-- [(1,4),(2,1),(3,2)]
--
elemCountOrd :: (Ord a) => [a] -> [(a, Int)]
elemCountOrd = map (\l -> (head l, length l) ) . group . sort
-- | for empty list
--
-- >>> elemCountEq []
-- []
--
-- | count the same element
--
-- >>> elemCountEq [1,1,1,2,2,3,1,2,3]
-- [(1,4),(2,3),(3,2)]
--
-- | target list not sorted, so result is order of appearance.
--
-- >>> elemCountEq [1,1,1,3,1,2,3]
-- [(1,4),(3,2),(2,1)]
--
elemCountEq :: (Eq a) => [a] -> [(a, Int)]
elemCountEq = map (\l -> (head l, length l) ) . groupSameElement
-- | group the same element on list
--
-- >>> groupSameElement [1,3,4,5,2,2,1,2,4]
-- [[1,1],[3],[4,4],[5],[2,2,2]]
--
groupSameElement :: (Eq a) => [a] -> [[a]]
groupSameElement [] = []
groupSameElement (x:xs) = [x:(filter (== x) xs)] ++ groupSameElement (filter (/= x) xs)
-- | get uniq list
--
-- >>> uniq [1,2,2,3,1]
-- [1,2,3]
--
-- | result is order of appearance
--
-- >>> uniq [2,3,2,1,1,1,5,3,4]
-- [2,3,1,5,4]
--
uniq :: (Eq a) => [a] -> [a]
uniq [] = []
uniq (x:xs) = x:(uniq (filter (/= x) xs))
-- | count same element
--
-- >>> countSameElement 1 [1,1,2]
-- 2
-- >>> countSameElement 0 [1,1,2]
-- 0
--
countSameElement :: (Eq a) => a -> [a] -> Int
countSameElement x = length . filter (== x)
-- | for empty list
--
-- >>> elemCountUniq []
-- []
--
-- | count the same element
--
-- >>> elemCountUniq [1,1,1,2,2,3,1,2,3]
-- [(1,4),(2,3),(3,2)]
--
-- | target list not sorted, so result is order of appearance.
--
-- >>> elemCountUniq [1,1,1,3,1,2,3]
-- [(1,4),(3,2),(2,1)]
--
elemCountUniq :: (Eq a) => [a] -> [(a,Int)]
-- elemCountUniq xs = zip uniqList (fmap (\x -> countSameElement x xs) uniqList)
-- where uniqList = uniq xs
elemCountUniq xs = fmap (\x -> (x, countSameElement x xs)) $ uniq xs
-- | for empty list
--
-- >>> elemCountOnce []
-- []
--
-- | count the same element
--
-- >>> elemCountOnce [1,1,1,2,2,3,1,2,3]
-- [(1,4),(2,3),(3,2)]
--
-- | target list not sorted, so result is order of appearance.
--
-- >>> elemCountOnce [1,1,1,3,1,2,3]
-- [(1,4),(3,2),(2,1)]
--
elemCountOnce :: Eq a => [a] -> [(a, Int)]
elemCountOnce [] = []
elemCountOnce (x:xs) = (x, (length $ filter (== x) xs) + 1) : elemCountOnce (filter (/= x) xs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment