Jaro similarity: Difference between revisions
m
→{{header|Haskell}}: Applied Hlint, Ormolu. Removed an import.
m (→{{header|Phix}}: added syntax colouring the hard way) |
m (→{{header|Haskell}}: Applied Hlint, Ormolu. Removed an import.) |
||
Line 1,500:
=={{header|Haskell}}==
<lang Haskell>import Data.List (
import Text.Printf (printf)▼
import Data.Maybe (mapMaybe)
▲import Text.Printf (printf)
---------------------- JARO DISTANCE ---------------------
jaro :: Ord a => [a] -> [a] -> Float
jaro x y
| otherwise =
[m, t] = [f, fromIntegral . transpositions] <*> [matches x y]▼
(1 / 3)
[s1, s2] = [f] <*> [x, y]▼
where
0 -> 0▼
f = fromIntegral . length
▲ _ -> (1 / 3) * ((m / s1) + (m / s2) + ((m - t) / m))
[m, t] =
<*> [matches x y]
matches :: Eq a => [a] -> [a] -> [(Int, a)]
matches s1 s2 =
let [(l1, xs), (l2, ys)] =
sortBy (comparing fst) ((length >>= (,)) <$> [s1, s2])▼
r = quot l2 2 - 1
in mapMaybe
( \(c, n) ->
-- Initial chars out of range ?
▲ ->
let offset = max 0 (n - (r + 1))
>>= (\i -> Just (offset + i, c
(zip xs [1 ..])
transpositions :: Ord a => [(Int, a)] -> Int
transpositions =
length
. filter (uncurry (>))
. (zip <*> tail)
main :: IO ()
main =
mapM_ putStrLn $
fmap
(\(s1, s2) -> intercalate " -> " [s1, s2, printf "%.3f\n" $ jaro s1 s2]) <$>▼
intercalate
, ("MARTHA", "MARHTA")▼
, ("JELLYFISH", "SMELLYFISH")▼
)
]</lang>▼
[ ("DWAYNE", "DUANE"),
("DIXON", "DICKSONX"),
▲ ]</lang>
{{Out}}
<pre>DWAYNE -> DUANE -> 0.822
|