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

Content added Content deleted
m (→‎{{header|Haskell}}: Minor tidying.)
(→‎{{header|Haskell}}: Simplified a groupBy expression using `on`)
Line 1,299: Line 1,299:
<lang Haskell>import Data.List (groupBy, intersperse, sort, transpose)
<lang Haskell>import Data.List (groupBy, intersperse, sort, transpose)
import Data.Char (ord, toUpper)
import Data.Char (ord, toUpper)
import Data.Function(on)
import Numeric (showHex)
import Numeric (showHex)



hexFromChar :: Char -> String
hexFromChar :: Char -> String
hexFromChar c = map toUpper $ showHex (ord c) ""
hexFromChar c = map toUpper $ showHex (ord c) ""

string :: String -> String
string :: String -> String
string xs = ('\"' : xs) ++ "\""
string xs = ('\"' : xs) <> "\""

char :: Char -> String
char :: Char -> String
char c = ['\'', c, '\'']
char c = ['\'', c, '\'']

size :: String -> String
size :: String -> String
size = show . length
size = show . length

positions :: (Int, Int) -> String
positions :: (Int, Int) -> String
positions (a, b) = show a ++ " " ++ show b
positions (a, b) = show a <> " " <> show b

forTable :: String -> [String]
forTable :: String -> [String]
forTable xs = string xs : go (allUnique xs)
forTable xs = string xs : go (allUnique xs)
Line 1,321: Line 1,323:
go Nothing = [size xs, "yes", "", "", ""]
go Nothing = [size xs, "yes", "", "", ""]
go (Just (u, ij)) = [size xs, "no", char u, hexFromChar u, positions ij]
go (Just (u, ij)) = [size xs, "no", char u, hexFromChar u, positions ij]

showTable :: Bool -> Char -> Char -> Char -> [[String]] -> String
showTable :: Bool -> Char -> Char -> Char -> [[String]] -> String
showTable _ _ _ _ [] = []
showTable _ _ _ _ [] = []
Line 1,329: Line 1,331:
(if header
(if header
then z : hr : zs
then z : hr : zs
else intersperse hr zss) ++
else intersperse hr zss) <>
[hr]
[hr]
where
where
vss = map (map length) contents
vss = map (map length) contents
ms = map maximum (transpose vss) :: [Int]
ms = map maximum (transpose vss) :: [Int]
hr = concatMap (\n -> sep : replicate n hor) ms ++ [sep]
hr = concatMap (\n -> sep : replicate n hor) ms <> [sep]
top = replicate (length hr) hor
top = replicate (length hr) hor
bss = map (map (`replicate` ' ') . zipWith (-) ms) vss
bss = map (map (`replicate` ' ') . zipWith (-) ms) vss
zss@(z:zs) =
zss@(z:zs) =
zipWith
zipWith
(\us bs -> concat (zipWith (\x y -> (ver : x) ++ y) us bs) ++ [ver])
(\us bs -> concat (zipWith (\x y -> (ver : x) <> y) us bs) <> [ver])
contents
contents
bss
bss

table xs =
table xs =
showTable
showTable
Line 1,351: Line 1,353:
(["string", "length", "all unique", "1st diff", "hex", "positions"] :
(["string", "length", "all unique", "1st diff", "hex", "positions"] :
map forTable xs)
map forTable xs)

allUnique
allUnique
:: (Ord b, Ord a, Num b, Enum b)
:: (Ord b, Ord a, Num b, Enum b)
=> [a] -> Maybe (a, (b, b))
=> [a] -> Maybe (a, (b, b))
allUnique xs = go . groupBy (\(x, _) (y, _) -> x == y) . sort . zip xs $ [0 ..]
allUnique xs = go . groupBy (on (==) fst) . sort . zip xs $ [0 ..]
where
where
go [] = Nothing
go [] = Nothing
go ([_]:us) = go us
go ([_]:us) = go us
go (((u, i):(_, j):_):_) = Just (u, (i, j))
go (((u, i):(_, j):_):_) = Just (u, (i, j))

main :: IO ()
main :: IO ()
main =
main =