Determine if a string has all unique characters: Difference between revisions

Content added Content deleted
Line 530: Line 530:
(zip [0 ..] xs))))
(zip [0 ..] xs))))


-- OR, fusing filter, toList and minimumByMay down to a single fold:
-- OR, fusing filter, toList, and minimumByMay down to a single fold:
duplicatedCharIndices_ :: String -> Maybe (Char, [Int])
duplicatedCharIndices_ :: String -> Maybe (Char, [Int])
duplicatedCharIndices_ xs =
duplicatedCharIndices_ xs =
M.foldrWithKey
let go k [_] mb = mb -- Unique.
go
go k xs Nothing = Just (k, xs) -- Duplicate.
Nothing
go k xs@(x:_) (Just (c, ys@(y:_))) =
if x < y
(foldl' --'
then Just (k, xs) -- Earlier duplicate.
(\a (i, c) -> M.insert c (maybe [i] (++ [i]) (M.lookup c a)) a)
else Just (c, ys)
M.empty
(zip [0 ..] xs))
in M.foldrWithKey
go
where
Nothing
go k [_] mb = mb -- Unique.
(foldl' --'
go k xs Nothing = Just (k, xs) -- Duplicate.
(\a (i, c) -> M.insert c (maybe [i] (++ [i]) (M.lookup c a)) a)
go k xs@(x:_) (Just (c, ys@(y:_))) =
M.empty
if x < y
(zip [0 ..] xs))
then Just (k, xs) -- Earlier duplicate.
else Just (c, ys)



---------------------------TEST----------------------------
---------------------------TEST----------------------------
Line 564: Line 566:
duplicatedCharIndices_
duplicatedCharIndices_
["", ".", "abcABC", "XYZ ZYX", "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"]
["", ".", "abcABC", "XYZ ZYX", "1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ"]



--------------------------DISPLAY--------------------------
--------------------------DISPLAY--------------------------
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
fTable s xShow fxShow f xs =
fTable s xShow fxShow f xs =
unlines $
let rjust n c = drop . length <*> (replicate n c ++)
w = maximum (length . xShow <$> xs)
s : fmap (((++) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs
where
in unlines $
s : fmap (((++) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs</lang>
rjust n c = drop . length <*> (replicate n c ++)
w = maximum (length . xShow <$> xs)</lang>
{{Out}}
{{Out}}
<pre>First duplicated character, if any:
<pre>First duplicated character, if any: