Add tasks for all the new languages
This commit is contained in:
parent
9dc3c2bb62
commit
bba7bfd280
13208 changed files with 134745 additions and 0 deletions
16
Task/Levenshtein-distance/Arc/levenshtein-distance.arc
Normal file
16
Task/Levenshtein-distance/Arc/levenshtein-distance.arc
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
(def levenshtein (str1 str2)
|
||||
(withs l1 len.str1
|
||||
l2 len.str2
|
||||
row range0:inc.l1
|
||||
|
||||
(times j l2
|
||||
(let next list.j
|
||||
(times i l1
|
||||
(push
|
||||
(inc:min
|
||||
car.next
|
||||
((if (is str1.i str2.j) dec id) car.row)
|
||||
(car:zap cdr row))
|
||||
next))
|
||||
(= row nrev.next)))
|
||||
row.l1))
|
||||
43
Task/Levenshtein-distance/ERRE/levenshtein-distance.erre
Normal file
43
Task/Levenshtein-distance/ERRE/levenshtein-distance.erre
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
PROGRAM LEVENSHTEIN
|
||||
|
||||
!$DYNAMIC
|
||||
DIM D%[0,0]
|
||||
|
||||
PROCEDURE LEVENSHTEIN(S$,T$->RES%)
|
||||
LOCAL I%,J%,M%
|
||||
FOR I%=0 TO LEN(S$) DO
|
||||
D%[I%,0]=I%
|
||||
END FOR
|
||||
FOR J%=0 TO LEN(T$) DO
|
||||
D%[0,J%]=J%
|
||||
END FOR
|
||||
FOR J%=1 TO LEN(T$) DO
|
||||
FOR I%=1 TO LEN(S$) DO
|
||||
IF MID$(S$,I%,1)=MID$(T$,J%,1) THEN
|
||||
D%[I%,J%]=D%[I%-1,J%-1]
|
||||
ELSE
|
||||
M%=D%[I%-1,J%-1]
|
||||
IF D%[I%,J%-1]<M% THEN M%=D%[I%,J%-1] END IF
|
||||
IF D%[I%-1,J%]<M% THEN M%=D%[I%-1,J%] END IF
|
||||
D%[I%,J%]=M%+1
|
||||
END IF
|
||||
END FOR
|
||||
END FOR
|
||||
RES%=D%[I%-1,J%-1]
|
||||
END PROCEDURE
|
||||
|
||||
BEGIN
|
||||
S$="kitten" T$="sitting"
|
||||
PRINT("'";S$;"' -> '";T$;"' has distance ";)
|
||||
!$DIM D%[LEN(S$),LEN(T$)]
|
||||
LEVENSHTEIN(S$,T$->RES%)
|
||||
PRINT(RES%)
|
||||
!$ERASE D%
|
||||
|
||||
S$="rosettacode" T$="raisethysword"
|
||||
PRINT("'";S$;"' -> '";T$;"' has distance ";)
|
||||
!$DIM D%[LEN(S$),LEN(T$)]
|
||||
LEVENSHTEIN(S$,T$->RES%)
|
||||
PRINT(RES%)
|
||||
!$ERASE D%
|
||||
END PROGRAM
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
;; Recursive version adapted from Clojure
|
||||
;; Added necessary memoization
|
||||
|
||||
(define (levenshtein str1 str2 (cost 0) (rest1 0) (rest2 0) (key null))
|
||||
(set! key (string-append str1 "|" str2))
|
||||
(if (get 'mem key) ;; memoized ?
|
||||
(get 'mem key)
|
||||
;; else memoize
|
||||
(putprop 'mem
|
||||
(let [(len1 (string-length str1))
|
||||
(len2 (string-length str2))]
|
||||
(cond ((zero? len1) len2)
|
||||
((zero? len2) len1)
|
||||
(else
|
||||
(set! cost (if (= (string-first str1) (string-first str2)) 0 1))
|
||||
(set! rest1 (string-rest str1))
|
||||
(set! rest2 (string-rest str2))
|
||||
(min (1+ (levenshtein rest1 str2))
|
||||
(1+ (levenshtein str1 rest2))
|
||||
(+ cost
|
||||
(levenshtein rest1 rest2 ))))))
|
||||
key)))
|
||||
|
||||
;; 😛 127 calls with memoization
|
||||
;; 😰 29737 calls without memoization
|
||||
(levenshtein "kitten" "sitting") → 3
|
||||
|
||||
(levenshtein "rosettacode" "raisethysword") → 8
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
' FB 1.05.0 Win64
|
||||
|
||||
' Uses the "iterative with two matrix rows" algorithm
|
||||
' referred to in the Wikipedia article.
|
||||
|
||||
Function min(x As Integer, y As Integer) As Integer
|
||||
Return IIf(x < y, x, y)
|
||||
End Function
|
||||
|
||||
Function levenshtein(s As String, t As String) As Integer
|
||||
' degenerate cases
|
||||
If s = t Then Return 0
|
||||
If s = "" Then Return Len(t)
|
||||
If t = "" Then Return Len(s)
|
||||
|
||||
' create two integer arrays of distances
|
||||
Dim v0(0 To Len(t)) As Integer '' previous
|
||||
Dim v1(0 To Len(t)) As Integer '' current
|
||||
|
||||
' initialize v0
|
||||
For i As Integer = 0 To Len(t)
|
||||
v0(i) = i
|
||||
Next
|
||||
|
||||
Dim cost As Integer
|
||||
For i As Integer = 0 To Len(s) - 1
|
||||
' calculate v1 from v0
|
||||
v1(0) = i + 1
|
||||
|
||||
For j As Integer = 0 To Len(t) - 1
|
||||
cost = IIf(s[i] = t[j], 0, 1)
|
||||
v1(j + 1) = min(v1(j) + 1, min(v0(j + 1) + 1, v0(j) + cost))
|
||||
Next j
|
||||
|
||||
' copy v1 to v0 for next iteration
|
||||
For j As Integer = 0 To Len(t)
|
||||
v0(j) = v1(j)
|
||||
Next j
|
||||
Next i
|
||||
|
||||
Return v1(Len(t))
|
||||
End Function
|
||||
|
||||
Print "'kitten' to 'sitting' => "; levenshtein("kitten", "sitting")
|
||||
Print "'rosettacode' to 'raisethysword' => "; levenshtein("rosettacode", "raisethysword")
|
||||
Print "'sleep' to 'fleeting' => "; levenshtein("sleep", "fleeting")
|
||||
Print
|
||||
Print "Press any key to quit"
|
||||
Sleep
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
include "ConsoleWindow"
|
||||
|
||||
local fn LevenshteinDistance( aStr as Str255, bStr as Str255 ) as long
|
||||
dim as long m, n, i, j, min, k, l
|
||||
dim as long distance( 255, 255 )
|
||||
|
||||
m = len(aStr)
|
||||
n = len(bStr)
|
||||
|
||||
for i = 0 to m
|
||||
distance( i, 0 ) = i
|
||||
next
|
||||
|
||||
for j = 0 to n
|
||||
distance( 0, j ) = j
|
||||
next
|
||||
|
||||
for j = 1 to n
|
||||
for i = 1 to m
|
||||
if mid$( aStr, i, 1 ) == mid$( bStr, j, 1 )
|
||||
distance( i, j ) = distance( i-1, j-1 )
|
||||
else
|
||||
min = distance( i-1, j ) + 1
|
||||
k = distance( i, j - 1 ) + 1
|
||||
l = distance( i-1, j-1 ) + 1
|
||||
if k < min then min = k
|
||||
if l < min then min = l
|
||||
distance( i, j ) = min
|
||||
end if
|
||||
next
|
||||
next
|
||||
end fn = distance( m, n )
|
||||
|
||||
dim as long i
|
||||
dim as Str255 testStr( 5, 2 )
|
||||
|
||||
testStr( 0, 0 ) = "kitten" : testStr( 0, 1 ) = "sitting"
|
||||
testStr( 1, 0 ) = "rosettacode" : testStr( 1, 1 ) = "raisethysword"
|
||||
testStr( 2, 0 ) = "Saturday" : testStr( 2, 1 ) = "Sunday"
|
||||
testStr( 3, 0 ) = "FutureBasic" : testStr( 3, 1 ) = "FutureBasic"
|
||||
testStr( 4, 0 ) = "here's a bunch of words"
|
||||
testStr( 4, 1 ) = "to wring out this code"
|
||||
|
||||
for i = 0 to 4
|
||||
print "1st string = "; testStr( i, 0 )
|
||||
print "2nd string = "; testStr( i, 1 )
|
||||
print "Levenshtein distance ="; fn LevenshteinDistance( testStr( i, 0 ), testStr( i, 1 ) )
|
||||
print
|
||||
next
|
||||
13
Task/Levenshtein-distance/LFE/levenshtein-distance-1.lfe
Normal file
13
Task/Levenshtein-distance/LFE/levenshtein-distance-1.lfe
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
(defun levenshtein-simple
|
||||
(('() str)
|
||||
(length str))
|
||||
((str '())
|
||||
(length str))
|
||||
(((cons a str1) (cons b str2)) (when (== a b))
|
||||
(levenshtein-simple str1 str2))
|
||||
(((= (cons _ str1-tail) str1) (= (cons _ str2-tail) str2))
|
||||
(+ 1 (lists:min
|
||||
(list
|
||||
(levenshtein-simple str1 str2-tail)
|
||||
(levenshtein-simple str1-tail str2)
|
||||
(levenshtein-simple str1-tail str2-tail))))))
|
||||
8
Task/Levenshtein-distance/LFE/levenshtein-distance-2.lfe
Normal file
8
Task/Levenshtein-distance/LFE/levenshtein-distance-2.lfe
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
> (levenshtein-simple "a" "a")
|
||||
0
|
||||
> (levenshtein-simple "a" "")
|
||||
1
|
||||
> (levenshtein-simple "" "a")
|
||||
1
|
||||
> (levenshtein-simple "kitten" "sitting")
|
||||
3
|
||||
26
Task/Levenshtein-distance/LFE/levenshtein-distance-3.lfe
Normal file
26
Task/Levenshtein-distance/LFE/levenshtein-distance-3.lfe
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
(defun levenshtein-distance (str1 str2)
|
||||
(let (((tuple distance _) (levenshtein-distance
|
||||
str1 str2 (dict:new))))
|
||||
distance))
|
||||
|
||||
(defun levenshtein-distance
|
||||
(((= '() str1) str2 cache)
|
||||
(tuple (length str2)
|
||||
(dict:store (tuple str1 str2)
|
||||
(length str2)
|
||||
cache)))
|
||||
((str1 (= '() str2) cache)
|
||||
(tuple (length str1)
|
||||
(dict:store (tuple str1 str2)
|
||||
(length str1)
|
||||
cache)))
|
||||
(((cons a str1) (cons b str2) cache) (when (== a b))
|
||||
(levenshtein-distance str1 str2 cache))
|
||||
(((= (cons _ str1-tail) str1) (= (cons _ str2-tail) str2) cache)
|
||||
(case (dict:is_key (tuple str1 str2) cache)
|
||||
('true (tuple (dict:fetch (tuple str1 str2) cache) cache))
|
||||
('false (let* (((tuple l1 c1) (levenshtein-distance str1 str2-tail cache))
|
||||
((tuple l2 c2) (levenshtein-distance str1-tail str2 c1))
|
||||
((tuple l3 c3) (levenshtein-distance str1-tail str2-tail c2))
|
||||
(len (+ 1 (lists:min (list l1 l2 l3)))))
|
||||
(tuple len (dict:store (tuple str1 str2) len c3)))))))
|
||||
10
Task/Levenshtein-distance/LFE/levenshtein-distance-4.lfe
Normal file
10
Task/Levenshtein-distance/LFE/levenshtein-distance-4.lfe
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
> (levenshtein-distance "a" "a")
|
||||
0
|
||||
> (levenshtein-distance "a" "")
|
||||
1
|
||||
> (levenshtein-distance "" "a")
|
||||
1
|
||||
> (levenshtein-distance "kitten" "sitting")
|
||||
3
|
||||
> (levenshtein-distance "rosettacode" "raisethysword")
|
||||
8
|
||||
24
Task/Levenshtein-distance/Nim/levenshtein-distance.nim
Normal file
24
Task/Levenshtein-distance/Nim/levenshtein-distance.nim
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import sequtils
|
||||
|
||||
proc levenshteinDistance(s1, s2): int =
|
||||
var (s1, s2) = (s1, s2)
|
||||
|
||||
if s1.len > s2.len:
|
||||
swap s1, s2
|
||||
|
||||
var distances = toSeq(0..s1.len)
|
||||
|
||||
for i2, c2 in s2:
|
||||
var newDistances = @[i2+1]
|
||||
for i1, c1 in s1:
|
||||
if c1 == c2:
|
||||
newDistances.add(distances[i1])
|
||||
else:
|
||||
newDistances.add(1 + min(distances[i1], distances[i1+1],
|
||||
newDistances[newDistances.high]))
|
||||
|
||||
distances = newDistances
|
||||
result = distances[distances.high]
|
||||
|
||||
echo levenshteinDistance("kitten","sitting")
|
||||
echo levenshteinDistance("rosettacode","raisethysword")
|
||||
35
Task/Levenshtein-distance/Phix/levenshtein-distance.phix
Normal file
35
Task/Levenshtein-distance/Phix/levenshtein-distance.phix
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
function levenshtein(sequence s1, sequence s2)
|
||||
integer n = length(s1)+1,
|
||||
m = length(s2)+1
|
||||
sequence d
|
||||
|
||||
if n=1 then
|
||||
return m-1
|
||||
elsif m=1 then
|
||||
return n-1
|
||||
end if
|
||||
|
||||
d = repeat(repeat(0, m), n)
|
||||
for i=1 to n do
|
||||
d[i][1] = i-1
|
||||
end for
|
||||
|
||||
for j=1 to m do
|
||||
d[1][j] = j-1
|
||||
end for
|
||||
|
||||
for i=2 to n do
|
||||
for j=2 to m do
|
||||
d[i][j] = min({
|
||||
d[i-1][j]+1,
|
||||
d[i][j-1]+1,
|
||||
d[i-1][j-1]+(s1[i-1]!=s2[j-1])
|
||||
})
|
||||
end for
|
||||
end for
|
||||
|
||||
return d[n][m]
|
||||
end function
|
||||
|
||||
?levenshtein("kitten", "sitting")
|
||||
?levenshtein("rosettacode", "raisethysword")
|
||||
15
Task/Levenshtein-distance/Sidef/levenshtein-distance-1.sidef
Normal file
15
Task/Levenshtein-distance/Sidef/levenshtein-distance-1.sidef
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
func lev(s, t) is cached {
|
||||
|
||||
s.is_empty && return t.len;
|
||||
t.is_empty && return s.len;
|
||||
|
||||
var s1 = s.ft(1);
|
||||
var t1 = t.ft(1);
|
||||
|
||||
s[0] == t[0] ? __FUNC__(s1, t1)
|
||||
: 1+[
|
||||
__FUNC__(s1, t1),
|
||||
__FUNC__(s, t1),
|
||||
__FUNC__(s1, t )
|
||||
].min;
|
||||
}
|
||||
11
Task/Levenshtein-distance/Sidef/levenshtein-distance-2.sidef
Normal file
11
Task/Levenshtein-distance/Sidef/levenshtein-distance-2.sidef
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
func lev(s, t) {
|
||||
var d = [@(0 .. t.len), s.len.of {[_]}...]
|
||||
for i,j in (^s ~X ^t) {
|
||||
d[i+1][j+1] = (
|
||||
s[i] == t[j]
|
||||
? d[i][j]
|
||||
: 1+Math.min(d[i][j+1], d[i+1][j], d[i][j])
|
||||
)
|
||||
}
|
||||
d[-1][-1]
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
say lev(%c'kitten', %c'sitting'); # prints: 3
|
||||
say lev(%c'rosettacode', %c'raisethysword'); # prints: 8
|
||||
15
Task/Levenshtein-distance/Swift/levenshtein-distance-1.swift
Normal file
15
Task/Levenshtein-distance/Swift/levenshtein-distance-1.swift
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
func levDis(w1: String, w2: String) -> Int {
|
||||
|
||||
let (t, s) = (w1.characters, w2.characters)
|
||||
|
||||
let empty = Repeat(count: s.count, repeatedValue: 0)
|
||||
var mat = [[Int](0...s.count)] + (1...t.count).map{[$0] + empty}
|
||||
|
||||
for (i, tLett) in t.enumerate() {
|
||||
for (j, sLett) in s.enumerate() {
|
||||
mat[i + 1][j + 1] = tLett == sLett ?
|
||||
mat[i][j] : min(mat[i][j], mat[i][j + 1], mat[i + 1][j]).successor()
|
||||
}
|
||||
}
|
||||
return mat.last!.last!
|
||||
}
|
||||
16
Task/Levenshtein-distance/Swift/levenshtein-distance-2.swift
Normal file
16
Task/Levenshtein-distance/Swift/levenshtein-distance-2.swift
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
func levDis(w1: String, w2: String) -> Int {
|
||||
|
||||
let (t, s) = (w1.characters, w2.characters)
|
||||
|
||||
let empty = Repeat(count: s.count, repeatedValue: 0)
|
||||
var last = [Int](0...s.count)
|
||||
|
||||
for (i, tLett) in t.enumerate() {
|
||||
var cur = [i + 1] + empty
|
||||
for (j, sLett) in s.enumerate() {
|
||||
cur[j + 1] = tLett == sLett ? last[j] : min(last[j], last[j + 1], cur[j]).successor()
|
||||
}
|
||||
last = cur
|
||||
}
|
||||
return last.last!
|
||||
}
|
||||
51
Task/Levenshtein-distance/jq/levenshtein-distance-1.jq
Normal file
51
Task/Levenshtein-distance/jq/levenshtein-distance-1.jq
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# lookup the distance between s and t in the nested cache,
|
||||
# which uses basic properties of the Levenshtein distance to save space:
|
||||
def lookup(s;t):
|
||||
if (s == t) then 0
|
||||
elif (s|length) == 0 then (t|length)
|
||||
elif (t|length) == 0 then (s|length)
|
||||
elif (s|length) > (t|length) then
|
||||
.[t] as $t | if $t then $t[s] else null end
|
||||
else .[s] as $s | if $s then $s[t] else null end
|
||||
end ;
|
||||
|
||||
# output is the updated cache;
|
||||
# basic properties of the Levenshtein distance are used to save space:
|
||||
def store(s;t;value):
|
||||
if (s == t) then .
|
||||
else (s|length) as $s | (t|length) as $t
|
||||
| if $s == 0 or $t == 0 then .
|
||||
elif $s < $t then .[s][t] = value
|
||||
elif $t < $s then .[t][s] = value
|
||||
else (.[s][t] = value) | (.[t][s] = value)
|
||||
end
|
||||
end ;
|
||||
|
||||
# Input is a cache of nested objects; output is [distance, cache]
|
||||
def ld(s1; s2):
|
||||
|
||||
# emit [distance, cache]
|
||||
# input: cache
|
||||
def cached_ld(s;t):
|
||||
lookup(s;t) as $check
|
||||
| if $check then [ $check, . ]
|
||||
else ld(s;t)
|
||||
end
|
||||
;
|
||||
|
||||
# If either string is empty,
|
||||
# then distance is insertion of the other's characters.
|
||||
if (s1|length) == 0 then [(s2|length), .]
|
||||
elif (s2|length) == 0 then [(s1|length), .]
|
||||
elif (s1[0:1] == s2[0:1]) then
|
||||
cached_ld(s1[1:]; s2[1:])
|
||||
else
|
||||
cached_ld(s1[1:]; s2) as $a
|
||||
| ($a[1] | cached_ld(s1; s2[1:])) as $b
|
||||
| ($b[1] | cached_ld(s1[1:]; s2[1:])) as $c
|
||||
| [$a[0], $b[0], $c[0]] | (min + 1) as $d
|
||||
| [$d, ($c[1] | store(s1;s2;$d)) ]
|
||||
end ;
|
||||
|
||||
def levenshteinDistance(s;t):
|
||||
s as $s | t as $t | {} | ld($s;$t) | .[0];
|
||||
8
Task/Levenshtein-distance/jq/levenshtein-distance-2.jq
Normal file
8
Task/Levenshtein-distance/jq/levenshtein-distance-2.jq
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
def demo:
|
||||
"levenshteinDistance between \(.[0]) and \(.[1]) is \( levenshteinDistance(.[0]; .[1]) )";
|
||||
|
||||
(["kitten", "sitting"] | demo),
|
||||
(["rosettacode","raisethysword"] | demo),
|
||||
(["edocattesor", "drowsyhtesiar"] | demo),
|
||||
(["this_algorithm_is_similar_to",
|
||||
"Damerau-Levenshtein_distance"] | demo)
|
||||
Loading…
Add table
Add a link
Reference in a new issue