sub distance (Str $first, Str $second) {
my int $m = $first.chars;
my int $n = $second.chars;
# distance matrix: ($m+1) x ($n+1) of integers
my @d;
@d[$_][0] = $_ for 0..$m; # deletion costs
@d[0][$_] = $_ for 0..$n; # insertion costs
# Pre‑extract characters as integers (faster than repeated .comb)
my @s = $first.ords;
my @t = $second.ords;
loop (my int $i = 1; $i <= $m; $i++) {
my int $s_i = @s[$i-1];
loop (my int $j = 1; $j <= $n; $j++) {
if $s_i == @t[$j-1] {
@d[$i][$j] = @d[$i-1][$j-1];
} else {
# Raku's built‑in min is concise and still fast for short strings
@d[$i][$j] = 1 + min(
@d[$i-1][$j], # deletion
@d[$i][$j-1], # insertion
@d[$i-1][$j-1] # substitution
);
}
}
}
@d[$m][$n];
}
use Test;
plan 15; # we will run 15 test cases
# Each test is: (string A, string B, expected_distance)
my @test_cases =
# Empty strings
("", "", 0),
("", "a", 1),
("", "ab", 2),
("a", "", 1),
("ab", "", 2),
# Single character
("a", "a", 0),
("a", "b", 1),
("a", "aa", 1),
("aa", "a", 1),
# Two characters
("ab", "ab", 0),
("ab", "ac", 1), # substitution
("ab", "a", 1), # deletion
("ab", "cab", 1), # insertion at front
# Longer strings
("kitten","sitting",3),
("saturday","sunday",3);
for @test_cases -> ($a, $b, $expected) {
my $got = distance($a, $b);
is $got, $expected, "distance('$a', '$b') == $expected";
}