Jump to content

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

→‎{{header|Haskell}}: Simplified a groupBy expression using `on`
m (→‎{{header|Haskell}}: Minor tidying.)
(→‎{{header|Haskell}}: Simplified a groupBy expression using `on`)
Line 1,299:
<lang Haskell>import Data.List (groupBy, intersperse, sort, transpose)
import Data.Char (ord, toUpper)
import Data.Function(on)
import Numeric (showHex)
 
 
hexFromChar :: Char -> String
hexFromChar c = map toUpper $ showHex (ord c) ""
 
string :: String -> String
string xs = ('\"' : xs) ++<> "\""
 
char :: Char -> String
char c = ['\'', c, '\'']
 
size :: String -> String
size = show . length
 
positions :: (Int, Int) -> String
positions (a, b) = show a ++<> " " ++<> show b
 
forTable :: String -> [String]
forTable xs = string xs : go (allUnique xs)
Line 1,321 ⟶ 1,323:
go Nothing = [size xs, "yes", "", "", ""]
go (Just (u, ij)) = [size xs, "no", char u, hexFromChar u, positions ij]
 
showTable :: Bool -> Char -> Char -> Char -> [[String]] -> String
showTable _ _ _ _ [] = []
Line 1,329 ⟶ 1,331:
(if header
then z : hr : zs
else intersperse hr zss) ++<>
[hr]
where
vss = map (map length) contents
ms = map maximum (transpose vss) :: [Int]
hr = concatMap (\n -> sep : replicate n hor) ms ++<> [sep]
top = replicate (length hr) hor
bss = map (map (`replicate` ' ') . zipWith (-) ms) vss
zss@(z:zs) =
zipWith
(\us bs -> concat (zipWith (\x y -> (ver : x) ++<> y) us bs) ++<> [ver])
contents
bss
 
table xs =
showTable
Line 1,351 ⟶ 1,353:
(["string", "length", "all unique", "1st diff", "hex", "positions"] :
map forTable xs)
 
allUnique
:: (Ord b, Ord a, Num b, Enum b)
=> [a] -> Maybe (a, (b, b))
allUnique xs = go . groupBy (\(x, _)on (y, _) -> x ==) yfst) . sort . zip xs $ [0 ..]
where
go [] = Nothing
go ([_]:us) = go us
go (((u, i):(_, j):_):_) = Just (u, (i, j))
 
main :: IO ()
main =
9,659

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.