-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathperagrams.hs
40 lines (34 loc) · 1.23 KB
/
peragrams.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import Data.List
import qualified Data.Map.Lazy as Map
-- O(length s)
--isPalindrome :: String -> Bool
--isPalindrome "" = True
--isPalindrome (_:"") = True
--isPalindrome (first:rest) =
-- -- 1. is the first character equal to the last, and
-- -- 2. is the middle of the string a palindrome
-- first == last rest && (isPalindrome $ init rest)
-- O(length anagram + length s)
--isAnagramOf :: String -> String -> Bool
--isAnagramOf anagram s =
-- -- tally the number of occurences of each character in `anagram` and compare
-- -- to that of `s`
-- charTally anagram == charTally s
-- O(length s)
charTally :: String -> Map.Map Char Int
charTally s = foldl folder Map.empty s
where folder map k = Map.insert k (Map.findWithDefault 0 k map + 1) map
-- O(1)
isPeragram :: Map.Map Char Int -> Bool
isPeragram m = Map.size (Map.filter (\v -> v `mod` 2 /= 0) m) <= 1
-- O(1)
minDeleteBecomePeragram :: Int -> Map.Map Char Int -> Int
minDeleteBecomePeragram num m
| isPeragram m = num
| otherwise =
minDeleteBecomePeragram (num + 1)
(Map.updateMin (\v -> Just $ subtract v 1) (Map.filter (\v -> v `mod` 2 /= 0) m))
main :: IO ()
main = do
line <- getLine
print $ minDeleteBecomePeragram 0 (charTally line)