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. for flat 1..@s.end X 1..@t.end -> $i, $j {
  26. @d[$i][$j] = @s[$i] eq @t[$j]
  27. ?? @d[$i-1][$j-1] # No operation required when eq
  28. !! ( @d[$i-1][$j ], # Deletion
  29. @d[$i ][$j-1], # Insertion
  30. @d[$i-1][$j-1], # Substitution
  31. ).min + 1;
  32. }
  33. @d.tail.tail;
  34. }
  35. }
  36. }