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