/
StrDistance.pm6
50 lines (41 loc) · 1.25 KB
/
StrDistance.pm6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
my class StrDistance is Cool {
has Str $.before;
has Str $.after;
has Int $!distance;
submethod BUILD(Str() :$!before, :$!after --> Nil) { }
method Bool() {
$.before ne $.after
}
method ACCEPTS(StrDistance:D: Mu \a) {
self
}
method Numeric() {
self.Int
}
method Str {
$.after
}
multi method Int(StrDistance:D:) {
$!distance //= do {
my @s = *, |$.before.comb;
my @t = *, |$.after.comb;
my @d;
@d[$_][ 0] = $_ for ^@s.end;
@d[ 0][$_] = $_ for ^@t.end;
my int $s_elems = @s.elems;
my int $t_elems = @t.elems;
loop (my int $i = 1; $i < $s_elems; $i = $i + 1) {
loop (my int $j = 1; $j < $t_elems; $j = $j + 1) {
@d[$i][$j] = @s[$i] eq @t[$j]
?? @d[$i-1][$j-1] # No operation required when eq
!! ( @d[$i-1][$j ], # Deletion
@d[$i ][$j-1], # Insertion
@d[$i-1][$j-1], # Substitution
).min + 1;
}
}
@d.tail.tail;
}
}
}
# vim: ft=perl6 expandtab sw=4