Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,18 @@
def levenshteinDistance(str1, str2):
m = len(str1)
n = len(str2)
d = [[i] for i in range(1, m + 1)] # d matrix rows
d.insert(0, list(range(0, n + 1))) # d matrix columns
for j in range(1, n + 1):
for i in range(1, m + 1):
if str1[i - 1] == str2[j - 1]: # Python (string) is 0-based
substitutionCost = 0
else:
substitutionCost = 1
d[i].insert(j, min(d[i - 1][j] + 1,
d[i][j - 1] + 1,
d[i - 1][j - 1] + substitutionCost))
return d[-1][-1]
print(levenshteinDistance("kitten","sitting"))
print(levenshteinDistance("rosettacode","raisethysword"))

View file

@ -0,0 +1,18 @@
def minimumEditDistance(s1,s2):
if len(s1) > len(s2):
s1,s2 = s2,s1
distances = range(len(s1) + 1)
for index2,char2 in enumerate(s2):
newDistances = [index2+1]
for index1,char1 in enumerate(s1):
if char1 == char2:
newDistances.append(distances[index1])
else:
newDistances.append(1 + min((distances[index1],
distances[index1+1],
newDistances[-1])))
distances = newDistances
return distances[-1]
print(minimumEditDistance("kitten","sitting"))
print(minimumEditDistance("rosettacode","raisethysword"))

View file

@ -0,0 +1,42 @@
def ld(a, b, mx=-1):
def result(d): return d if mx < 0 else False if d > mx else True
if a == b: return result(0)
la, lb = len(a), len(b)
if mx >= 0 and abs(la - lb) > mx: return result(mx+1)
if la == 0: return result(lb)
if lb == 0: return result(la)
if lb > la: a, b, la, lb = b, a, lb, la
cost = array('i', range(lb + 1))
for i in range(1, la + 1):
cost[0] = i; ls = i-1; mn = ls
for j in range(1, lb + 1):
ls, act = cost[j], ls + int(a[i-1] != b[j-1])
cost[j] = min(ls+1, cost[j-1]+1, act)
if (ls < mn): mn = ls
if mx >= 0 and mn > mx: return result(mx+1)
if mx >= 0 and cost[lb] > mx: return result(mx+1)
return result(cost[lb])
print(
ld('kitten','kitten'), # 0
ld('kitten','sitten'), # 1
ld('kitten','sittes'), # 2
ld('kitten','sityteng'), # 3
ld('kitten','sittYing'), # 4
ld('rosettacode','raisethysword'), # 8
ld('kitten','kittenaaaaaaaaaaaaaaaaa'), # 17
ld('kittenaaaaaaaaaaaaaaaaa','kitten') # 17
)
print(
ld('kitten','kitten',3), # True
ld('kitten','sitten',3), # True
ld('kitten','sittes',3), # True
ld('kitten','sityteng',3), # True
ld('kitten','sittYing',3), # False
ld('rosettacode','raisethysword',3), # False
ld('kitten','kittenaaaaaaaaaaaaaaaaa',3), # False
ld('kittenaaaaaaaaaaaaaaaaa','kitten',3) # False
)

View file

@ -0,0 +1,13 @@
>>> from functools import lru_cache
>>> @lru_cache(maxsize=4095)
def ld(s, t):
if not s: return len(t)
if not t: return len(s)
if s[0] == t[0]: return ld(s[1:], t[1:])
l1 = ld(s, t[1:])
l2 = ld(s[1:], t)
l3 = ld(s[1:], t[1:])
return 1 + min(l1, l2, l3)
>>> print( ld("kitten","sitting"),ld("rosettacode","raisethysword") )
3 8

View file

@ -0,0 +1,147 @@
'''Levenshtein distance'''
from itertools import (accumulate, chain, islice)
from functools import reduce
# levenshtein :: String -> String -> Int
def levenshtein(sa):
'''Levenshtein distance between
two strings.'''
s1 = list(sa)
# go :: [Int] -> Char -> [Int]
def go(ns, c):
n, ns1 = ns[0], ns[1:]
# gap :: Int -> (Char, Int, Int) -> Int
def gap(z, c1xy):
c1, x, y = c1xy
return min(
succ(y),
succ(z),
succ(x) if c != c1 else x
)
return scanl(gap)(succ(n))(
zip(s1, ns, ns1)
)
return lambda sb: reduce(
go, list(sb), enumFromTo(0)(len(s1))
)[-1]
# TEST ----------------------------------------------------
# main :: IO ()
def main():
'''Tests'''
pairs = [
('rosettacode', 'raisethysword'),
('kitten', 'sitting'),
('saturday', 'sunday')
]
print(
tabulated(
'Levenshtein minimum edit distances:\n'
)(str)(str)(
uncurry(levenshtein)
)(concat(map(
list,
zip(pairs, map(swap, pairs))
)))
)
# GENERIC -------------------------------------------------
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
'''Right to left function composition.'''
return lambda f: lambda x: g(f(x))
# concat :: [[a]] -> [a]
# concat :: [String] -> String
def concat(xxs):
'''The concatenation of all the elements in a list.'''
xs = list(chain.from_iterable(xxs))
unit = '' if isinstance(xs, str) else []
return unit if not xs else (
''.join(xs) if isinstance(xs[0], str) else xs
)
# enumFromTo :: (Int, Int) -> [Int]
def enumFromTo(m):
'''Integer enumeration from m to n.'''
return lambda n: list(range(m, 1 + n))
# scanl :: (b -> a -> b) -> b -> [a] -> [b]
def scanl(f):
'''scanl is like reduce, but returns a succession of
intermediate values, building from the left.'''
return lambda a: lambda xs: (
list(accumulate(chain([a], xs), f))
)
# swap :: (a, b) -> (b, a)
def swap(tpl):
'''The swapped components of a pair.'''
return (tpl[1], tpl[0])
# succ :: Int => Int -> Int
def succ(x):
'''The successor of a value.
For numeric types, (1 +).'''
return 1 + x
# tabulated :: String -> (a -> String) ->
# (b -> String) ->
# (a -> b) -> [a] -> String
def tabulated(s):
'''Heading -> x display function ->
fx display function ->
f -> value list -> tabular string.'''
def go(xShow, fxShow, f, xs):
w = max(map(compose(len)(xShow), xs))
return s + '\n' + '\n'.join([
xShow(x).rjust(w, ' ') + ' -> ' + fxShow(f(x))
for x in xs
])
return lambda xShow: lambda fxShow: (
lambda f: lambda xs: go(
xShow, fxShow, f, xs
)
)
# take :: Int -> [a] -> [a]
# take :: Int -> String -> String
def take(n):
'''The prefix of xs of length n,
or xs itself if n > length xs.'''
return lambda xs: (
xs[0:n]
if isinstance(xs, list)
else list(islice(xs, n))
)
# uncurry :: (a -> b -> c) -> ((a, b) -> c)
def uncurry(f):
'''A function over a tuple
derived from a curried function.'''
return lambda xy: f(xy[0])(
xy[1]
)
# MAIN ---
if __name__ == '__main__':
main()