Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View 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))

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View 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))))))

View file

@ -0,0 +1,8 @@
> (levenshtein-simple "a" "a")
0
> (levenshtein-simple "a" "")
1
> (levenshtein-simple "" "a")
1
> (levenshtein-simple "kitten" "sitting")
3

View 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)))))))

View 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

View 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")

View 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")

View 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;
}

View 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]
}

View file

@ -0,0 +1,2 @@
say lev(%c'kitten', %c'sitting'); # prints: 3
say lev(%c'rosettacode', %c'raisethysword'); # prints: 8

View 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!
}

View 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!
}

View 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];

View 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)