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 |
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 |
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) |
(\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 ( |
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 = |