Skip to content

Instantly share code, notes, and snippets.

@paolino
Last active November 2, 2022 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paolino/dcb99abfc09e4115d5c12303833ef50a to your computer and use it in GitHub Desktop.
Save paolino/dcb99abfc09e4115d5c12303833ef50a to your computer and use it in GitHub Desktop.
fixpoint + dynamic programming implementation of levenshtein distance
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE TupleSections #-}
{-# HLINT ignore "Redundant multi-way if" #-}
import Control.Monad.Fix (fix)
import Data.Array (Array, array)
import qualified Data.Array as A
levCachedArray :: Eq a => [a] -> [a] -> Int
levCachedArray xs ys =
let bs@(bx, by) = (length xs, length ys)
in (A.! (0, 0)) $ fix $ \a ->
Data.Array.array ((0, 0), bs) $
[((x, by), bx - x) | x <- [0 .. bx]]
<> [((bx, y), by - y) | y <- [0 .. by]]
<> do
(nx, x) <- zip [0 ..] xs
(ny, y) <- zip [0 ..] ys
pure $
((nx, ny),) $
if
| x == y -> a A.! (succ nx, succ ny)
| otherwise -> 1 + minimum ((a A.!) <$> [(succ nx, succ ny), (nx, succ ny), (succ nx, ny)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment