aboutsummaryrefslogtreecommitdiff
path: root/challenge-096
diff options
context:
space:
mode:
authorPaulo Custodio <pauloscustodio@gmail.com>2021-02-21 18:37:56 +0000
committerPaulo Custodio <pauloscustodio@gmail.com>2021-02-21 18:37:56 +0000
commit5d209f5becaf87702814500faf2dfc102fddab18 (patch)
tree3456eeceaaacd8261593ba561b0e2ac338fae87d /challenge-096
parent798c5692eb4c43474a1ba230bb93f9fdfc3fd311 (diff)
downloadperlweeklychallenge-club-5d209f5becaf87702814500faf2dfc102fddab18.tar.gz
perlweeklychallenge-club-5d209f5becaf87702814500faf2dfc102fddab18.tar.bz2
perlweeklychallenge-club-5d209f5becaf87702814500faf2dfc102fddab18.zip
Add Ada solution to challenge 096
Simplify all the other solutions: output only the number of steps, as requested, and not the list of steps.
Diffstat (limited to 'challenge-096')
-rw-r--r--challenge-096/paulo-custodio/ada/ch_1.adb61
-rw-r--r--challenge-096/paulo-custodio/ada/ch_2.adb79
-rw-r--r--challenge-096/paulo-custodio/basic/ch-2.bas78
-rw-r--r--challenge-096/paulo-custodio/c/ch-2.c77
-rw-r--r--challenge-096/paulo-custodio/cpp/ch-2.cpp77
-rw-r--r--challenge-096/paulo-custodio/forth/ch-2.fs69
-rw-r--r--challenge-096/paulo-custodio/lua/ch-2.lua60
-rw-r--r--challenge-096/paulo-custodio/perl/ch-2.pl55
-rw-r--r--challenge-096/paulo-custodio/perl/ch-2a.pl3
-rw-r--r--challenge-096/paulo-custodio/python/ch-2.py50
-rw-r--r--challenge-096/paulo-custodio/t/test-2.yaml11
11 files changed, 164 insertions, 456 deletions
diff --git a/challenge-096/paulo-custodio/ada/ch_1.adb b/challenge-096/paulo-custodio/ada/ch_1.adb
new file mode 100644
index 0000000000..0c59a701e2
--- /dev/null
+++ b/challenge-096/paulo-custodio/ada/ch_1.adb
@@ -0,0 +1,61 @@
+-- Challenge 096
+--
+-- TASK #1 › Reverse Words
+-- Submitted by: Mohammad S Anwar
+-- You are given a string $S.
+--
+-- Write a script to reverse the order of words in the given string. The string
+-- may contain leading/trailing spaces. The string may have more than one space
+-- between words in the string. Print the result without leading/trailing spaces
+-- and there should be only one space between words.
+--
+-- Example 1:
+-- Input: $S = "The Weekly Challenge"
+-- Output: "Challenge Weekly The"
+
+with Ada.Command_Line;
+with Ada.Strings.Bounded;
+with Ada.Strings.Fixed; use Ada.Strings.Fixed;
+with Ada.Strings.Maps; use Ada.Strings.Maps;
+with Ada.Strings; use Ada.Strings;
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure ch_1 is
+ -- command line arguments
+ package CL renames Ada.Command_Line;
+
+ -- bounded strings
+ package SB is new Ada.Strings.Bounded.Generic_Bounded_Length(Max => 100);
+ use SB;
+
+ -- join command line arguments
+ function join_args return String is
+ text : SB.Bounded_String;
+ begin
+ for i in 1 .. CL.Argument_Count loop
+ text := text & CL.Argument(i) & " ";
+ end loop;
+ SB.Trim(text, Ada.Strings.Both);
+ return To_String(text);
+ end join_args;
+
+ -- reverse input string
+ function reverse_string(text : String) return String is
+ out_text : SB.Bounded_String;
+ Whitespace : constant Character_Set := To_Set (' ');
+ idx, first, last : Integer;
+ begin
+ idx := 1;
+ while idx in text'Range loop
+ Find_Token(text, Whitespace, idx, Outside, first, last);
+ exit when last = 0;
+ out_text := text(first .. last) & " " & out_text;
+ idx := last + 1;
+ end loop;
+ SB.Trim(out_text, Ada.Strings.Both);
+ return To_String(out_text);
+ end reverse_string;
+
+begin
+ Put_Line(reverse_string(join_args));
+end ch_1;
diff --git a/challenge-096/paulo-custodio/ada/ch_2.adb b/challenge-096/paulo-custodio/ada/ch_2.adb
new file mode 100644
index 0000000000..b29a6f22e1
--- /dev/null
+++ b/challenge-096/paulo-custodio/ada/ch_2.adb
@@ -0,0 +1,79 @@
+-- Challenge 096
+--
+-- TASK #2 › Edit Distance
+-- Submitted by: Mohammad S Anwar
+-- You are given two strings $S1 and $S2.
+--
+-- Write a script to find out the minimum operations required to convert $S1
+-- into $S2. The operations can be insert, remove or replace a character. Please
+-- check out Wikipedia page for more information.
+--
+-- Example 1:
+-- Input: $S1 = "kitten"; $S2 = "sitting"
+-- Output: 3
+--
+-- Operation 1: replace 'k' with 's'
+-- Operation 2: replace 'e' with 'i'
+-- Operation 3: insert 'g' at the end
+-- Example 2:
+-- Input: $S1 = "sunday"; $S2 = "monday"
+-- Output: 2
+--
+-- Operation 1: replace 's' with 'm'
+-- Operation 2: replace 'u' with 'o'
+
+with Ada.Command_Line;
+with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure ch_2 is
+ -- command line arguments
+ package CL renames Ada.Command_Line;
+
+ -- integer formatting
+ package Integer_IO is new Ada.Text_IO.Integer_IO (Integer);
+
+ -- compute Wagner-Fischer distance
+ function wag_fish_dist(a, b : String) return Integer is
+ d : array(a'First-1 .. a'Last, b'First-1 .. b'Last) of Integer;
+ subst_cost : Integer;
+ begin
+ -- zero table
+ for i in a'First-1 .. a'Last loop
+ for j in b'First-1 .. b'Last loop
+ d(i, j) := 0;
+ end loop;
+ end loop;
+
+ -- source prefixes can be transformed into empty string by dropping chars
+ for i in a'Range loop
+ d(i, a'First-1) := i;
+ end loop;
+
+ -- target prefixes can be reached from empty source prefix by inserting chars
+ for j in b'Range loop
+ d(b'First-1, j) := j;
+ end loop;
+
+ -- flood-fill the rest of the table
+ for j in b'Range loop
+ for i in a'Range loop
+ if a(i) = b(j) then
+ subst_cost := 0;
+ else
+ subst_cost := 1;
+ end if;
+ d(i, j) := Integer'Min(d(i-1, j )+1, -- deletion
+ Integer'Min(d(i, j-1)+1, -- insertion
+ d(i-1, j-1)+subst_cost)); -- substitution
+ end loop;
+ end loop;
+
+ -- distance is in lower bottom cell
+ return d(a'Last, b'Last);
+ end wag_fish_dist;
+
+begin
+ Integer_IO.Put(wag_fish_dist(CL.Argument(1), CL.Argument(2)), 0);
+ Put_Line("");
+end ch_2;
diff --git a/challenge-096/paulo-custodio/basic/ch-2.bas b/challenge-096/paulo-custodio/basic/ch-2.bas
index 669ab1bebf..ff29be1017 100644
--- a/challenge-096/paulo-custodio/basic/ch-2.bas
+++ b/challenge-096/paulo-custodio/basic/ch-2.bas
@@ -21,13 +21,6 @@
'
' Operation 1: replace 's' with 'm'
' Operation 2: replace 'u' with 'o'
-'
-' NOTE: the Wagner-Fischer Distance algorithm builds a table of distances
-' from which the operations can be deduced
-
-const E as integer = 1
-const S as integer = 2
-const SE as integer = 3
function min(a as integer, b as integer) as integer
if a < b then
@@ -41,9 +34,8 @@ function min3(a as integer, b as integer, c as integer) as integer
min3 = min(a, min(b, c))
end function
-sub wag_fish_dist(a as string, b as string)
- dim i as integer, j as integer, stp as integer, subst_cost as integer
- dim min_dr as integer, min_delta as integer, dr as integer, delta as integer
+function wag_fish_dist(a as string, b as string) as integer
+ dim i as integer, j as integer, subst_cost as integer
' define a table where d(i,j) is the Levenshtein distance between
' first i chars of a and first j chars of b
@@ -74,67 +66,7 @@ sub wag_fish_dist(a as string, b as string)
next j
' distance is in lower bottom cell
- print trim(str(d(len(a),len(b))))
-
- ' traverse the minimum path
- i = 0: j = 0
- do while i < len(a) or j < len(b)
- dr = 0: delta = 0: min_dr = 0: min_delta = len(a)+len(b)
-
- ' search shortest path in priority SE, E, S
- if i < len(a) and j < len(b) then
- dr = SE: delta = d(i+1,j+1) - d(i,j)
- if delta < min_delta then
- min_dr = dr: min_delta = delta
- end if
- end if
- if j < len(b) then
- dr = E: delta = d(i,j+1) - d(i,j)
- if delta < min_delta then
- min_dr = dr: min_delta = delta
- end if
- end if
- if i < len(a) then
- dr = S: delta = d(i+1,j) - d(i,j)
- if delta < min_delta then
- min_dr = dr: min_delta = delta
- end if
- end if
-
- ' apply shortest path and show steps
- select case min_dr
- case SE
- i += 1: j += 1
- if mid(a,i,1) <> mid(b,j,1) then
- stp += 1
- print "Operation"; stp; ": replace '"; _
- mid(a,i,1); "' with '"; mid(b,j,1); "'"
- end if
- case E
- j += 1
- stp += 1
- if j = len(b) then
- print "Operation"; stp; ": insert '"; _
- mid(b,j,1); "' at end"
- else
- print "Operation"; stp; ": insert '"; _
- mid(b,j,1); "' at position"; j
- end if
- case S
- i += 1
- stp += 1
- if i = len(a) then
- print "Operation"; stp; ": insert '"; _
- mid(a,i,1); "' at end"
- else
- print "Operation"; stp; ": insert '"; _
- mid(a,i,1); "' at position"; i
- end if
- case else
- assert(false)
- end select
- loop
-end sub
-
+ wag_fish_dist = d(len(a), len(b))
+end function
-wag_fish_dist command(1), command(2)
+print trim(str(wag_fish_dist(command(1), command(2))))
diff --git a/challenge-096/paulo-custodio/c/ch-2.c b/challenge-096/paulo-custodio/c/ch-2.c
index e4dd334e60..bea1fdab84 100644
--- a/challenge-096/paulo-custodio/c/ch-2.c
+++ b/challenge-096/paulo-custodio/c/ch-2.c
@@ -22,9 +22,6 @@ Output: 2
Operation 1: replace 's' with 'm'
Operation 2: replace 'u' with 'o'
-
-NOTE: the Wagner-Fischer Distance algorithm builds a table of distances
- from which the operations can be deduced
*/
#include <assert.h>
@@ -51,7 +48,7 @@ int min3(int a, int b, int c) {
enum { DIR_NONE, DIR_E, DIR_S, DIR_SE };
-void wag_fis_dist(const char* a, const char* b) {
+int wag_fis_dist(const char* a, const char* b) {
int len_a = strlen(a);
int len_b = strlen(b);
@@ -80,78 +77,14 @@ void wag_fis_dist(const char* a, const char* b) {
}
// distance is in lower bottom cell
- printf("%d\n", d[len_a][len_b]);
-
- // traverse the minimum path
- int i = 0, j = 0, step = 0;
- while (i < len_a || j < len_b) {
- int min_dir = DIR_NONE, min_delta = INT_MAX;
- int dir, delta;
-
- // search shortest path in priority SE, E, S
- if (i < len_a && j < len_b) {
- dir = DIR_SE;
- delta = d[i+1][j+1] - d[i][j];
- if (delta < min_delta) {
- min_dir = dir;
- min_delta = delta;
- }
- }
-
- if (j < len_b) {
- dir = DIR_E;
- delta = d[i][j+1] - d[i][j];
- if (delta < min_delta) {
- min_dir = dir;
- min_delta = delta;
- }
- }
-
- if (i < len_a) {
- dir = DIR_S;
- delta = d[i+1][j] - d[i][j];
- if (delta < min_delta) {
- min_dir = dir;
- min_delta = delta;
- }
- }
-
- // apply shortest path and show steps
- switch (min_dir) {
- case DIR_SE:
- i++; j++;
- if (a[i-1] != b[j-1]) {
- printf("Operation %d: replace '%c' with '%c'\n",
- ++step, a[i-1], b[j-1]);
- }
- break;
- case DIR_E:
- j++;
- if (j == len_b)
- printf("Operation %d: insert '%c' at end\n",
- ++step, b[j-1]);
- else
- printf("Operation %d: insert '%c' at position %d\n",
- ++step, b[j-1], j);
- break;
- case DIR_S:
- i++;
- if (i == len_a)
- printf("Operation %d: delete '%c' at end\n",
- ++step, a[i-1]);
- else
- printf("Operation %d: delete '%c' at position %d\n",
- ++step, a[i-1], i);
- break;
- default:
- assert(0);
- }
- }
+ int ret_value = d[len_a][len_b];
// free memory
for (int i = 0; i <= len_a; i++)
free(d[i]);
free(d);
+
+ return ret_value;
}
int main(int argc, char* argv[]) {
@@ -160,5 +93,5 @@ int main(int argc, char* argv[]) {
return EXIT_FAILURE;
}
- wag_fis_dist(argv[1], argv[2]);
+ printf("%d\n", wag_fis_dist(argv[1], argv[2]));
}
diff --git a/challenge-096/paulo-custodio/cpp/ch-2.cpp b/challenge-096/paulo-custodio/cpp/ch-2.cpp
index 4f4b5a1954..82d368f12a 100644
--- a/challenge-096/paulo-custodio/cpp/ch-2.cpp
+++ b/challenge-096/paulo-custodio/cpp/ch-2.cpp
@@ -22,9 +22,6 @@ Output: 2
Operation 1: replace 's' with 'm'
Operation 2: replace 'u' with 'o'
-
-NOTE: the Wagner-Fischer Distance algorithm builds a table of distances
- from which the operations can be deduced
*/
#include <algorithm>
@@ -38,9 +35,7 @@ int min3(int a, int b, int c) {
return std::min(a, std::min(b, c));
}
-enum class Dir { None, E, S, SE };
-
-void wag_fis_dist(const std::string& a, const std::string& b) {
+int wag_fis_dist(const std::string& a, const std::string& b) {
size_t len_a = a.size();
size_t len_b = b.size();
@@ -71,73 +66,7 @@ void wag_fis_dist(const std::string& a, const std::string& b) {
}
// distance is in lower bottom cell
- std::cout << d[len_a][len_b] << std::endl;
-
- // traverse the minimum path
- size_t i = 0, j = 0, step = 0;
- while (i < len_a || j < len_b) {
- Dir min_dir = Dir::None, dir;
- int min_delta = INT_MAX, delta;
-
- // search shortest path in priority SE, E, S
- if (i < len_a && j < len_b) {
- dir = Dir::SE;
- delta = d[i+1][j+1] - d[i][j];
- if (delta < min_delta) {
- min_dir = dir;
- min_delta = delta;
- }
- }
-
- if (j < len_b) {
- dir = Dir::E;
- delta = d[i][j+1] - d[i][j];
- if (delta < min_delta) {
- min_dir = dir;
- min_delta = delta;
- }
- }
-
- if (i < len_a) {
- dir = Dir::S;
- delta = d[i+1][j] - d[i][j];
- if (delta < min_delta) {
- min_dir = dir;
- min_delta = delta;
- }
- }
-
- // apply shortest path and show steps
- switch (min_dir) {
- case Dir::SE:
- i++; j++;
- if (a[i-1] != b[j-1]) {
- std::cout << "Operation " << ++step << ": replace '"
- << a[i-1] << "' with '" << b[j-1] << "'" << std::endl;
- }
- break;
- case Dir::E:
- j++;
- if (j == len_b)
- std::cout << "Operation " << ++step << ": insert '"
- << b[j-1] << "' at end" << std::endl;
- else
- std::cout << "Operation " << ++step << ": insert '"
- << b[j-1] << "' at position " << j << std::endl;
- break;
- case Dir::S:
- i++;
- if (i == len_a)
- std::cout << "Operation " << ++step << ": delete '"
- << a[i-1] << "' at end" << std::endl;
- else
- std::cout << "Operation " << ++step << ": delete '"
- << a[i-1] << "' at position " << i << std::endl;
- break;
- default:
- assert(0);
- }
- }
+ return d[len_a][len_b];
}
int main(int argc, char* argv[]) {
@@ -146,5 +75,5 @@ int main(int argc, char* argv[]) {
return EXIT_FAILURE;
}
- wag_fis_dist(argv[1], argv[2]);
+ std::cout << wag_fis_dist(argv[1], argv[2]) << std::endl;
}
diff --git a/challenge-096/paulo-custodio/forth/ch-2.fs b/challenge-096/paulo-custodio/forth/ch-2.fs
index 85543ee453..f99b0112c7 100644
--- a/challenge-096/paulo-custodio/forth/ch-2.fs
+++ b/challenge-096/paulo-custodio/forth/ch-2.fs
@@ -23,9 +23,6 @@
\
\ Operation 1: replace 's' with 'm'
\ Operation 2: replace 'u' with 'o'
-\
-\ NOTE: the Wagner-Fischer Distance algorithm builds a table of distances
-\ from which the operations can be deduced
\ collect arguments - strings a and b
@@ -85,69 +82,9 @@ len_a 1+ len_b 1+ * CELLS ALLOT
: .num ( n -- )
0 U.R ;
-\ output step
-0 VALUE step
-: show_operation ( -- )
- step 1+ TO step
- ." Operation " step .num ." : " ;
-
-\ traverse minimum path
-: traverse_path ( -- )
- 0 0 { i j } \ starting point
- BEGIN i len_a < j len_b < OR WHILE
- 0 { min_dir } len_a len_b + { min_delta }
- 0 { dir } 0 { delta }
-
- \ search shortest path in priority SE (D), E, S
- i len_a < j len_b < AND IF
- 'D' TO dir
- i 1+ j 1+ d[] @ i j d[] @ - TO delta
- delta min_delta < IF
- dir TO min_dir
- delta TO min_delta
- THEN
- THEN
-
- j len_b < IF
- 'E' TO dir
- i j 1+ d[] @ i j d[] @ - TO delta
- delta min_delta < IF
- dir TO min_dir
- delta TO min_delta
- THEN
- THEN
-
- i len_a < IF
- 'S' TO dir
- i 1+ j d[] @ i j d[] @ - TO delta
- delta min_delta < IF
- dir TO min_dir
- delta TO min_delta
- THEN
- THEN
-
- \ apply shortest path and show steps
- min_dir 'D' = IF
- i 1+ TO i
- j 1+ TO j
- i a[]@ j b[]@ <> IF
- show_operation ." replace '" i a[]@ EMIT ." ' with '" j b[]@ EMIT ." '" CR
- THEN
- ELSE min_dir 'E' = IF
- j 1+ TO j
- show_operation ." insert '" j b[]@ EMIT ." ' at "
- j len_b = IF ." end" ELSE ." position " j .num THEN CR
- ELSE min_dir 'S' = IF
- i 1+ TO i
- show_operation ." delete '" i a[]@ EMIT ." ' at "
- j len_b = IF ." end" ELSE ." position " i .num THEN CR
- THEN THEN THEN
- REPEAT ;
-
-: wag_fis_dist ( -- )
+: wag_fis_dist ( -- n )
clear_d init_source init_target flood_fill
- len_a len_b d[] @ . CR \ show distance
- traverse_path ;
+ len_a len_b d[] @ ;
-wag_fis_dist
+wag_fis_dist .num CR
BYE
diff --git a/challenge-096/paulo-custodio/lua/ch-2.lua b/challenge-096/paulo-custodio/lua/ch-2.lua
index a937ce3105..8ed87ff524 100644
--- a/challenge-096/paulo-custodio/lua/ch-2.lua
+++ b/challenge-096/paulo-custodio/lua/ch-2.lua
@@ -24,9 +24,6 @@ Challenge 096
#
# Operation 1: replace 's' with 'm'
# Operation 2: replace 'u' with 'o'
-
-# NOTE: the Wagner-Fischer Distance algorithm builds a table of distances
-# from which the operations can be deduced
--]]
function wag_fis_dist(a, b)
@@ -57,60 +54,7 @@ function wag_fis_dist(a, b)
end
-- distance is in lower bottom cell
- io.write(d[#a][#b], "\n")
-
- -- traverse the minimum path
- local i, j, step = 0, 0, 0
- while i < #a or j < #b do
- local dir, delta, min_dir, min_delta = 0,0,0,#a+#b
-
- -- search shortest path in priority SE, E, S
- if i < #a and j < #b then
- dir, delta = 'SE', d[i+1][j+1] - d[i][j]
- if delta < min_delta then min_dir, min_delta = dir, delta; end
- end
- if j < #b then
- dir, delta = 'E', d[i][j+1] - d[i][j]
- if delta < min_delta then min_dir, min_delta = dir, delta; end
- end
- if i < #a then
- dir, delta = 'S', d[i+1][j] - d[i][j]
- if delta < min_delta then min_dir, min_delta = dir, delta; end
- end
-
- -- apply shortest path and show steps
- if min_dir == 'SE' then
- i, j = i+1, j+1
- if string.sub(a,i,i) ~= string.sub(b,j,j) then
- step = step+1
- io.write("Operation ", step, ": replace '",
- string.sub(a,i,i), "' with '",
- string.sub(b,j,j), "'\n")
- end
- elseif min_dir == 'E' then
- j = j+1
- step = step+1
- if j == #b then
- io.write("Operation ", step, ": insert '",
- string.sub(b,j,j), "' at end\n")
- else
- io.write("Operation ", step, ": insert '",
- string.sub(b,j,j), "' at position ", j, "\n")
- end
- elseif min_dir == 'S' then
- i = i+1
- step = step+1
- if i == #a then
- io.write("Operation ", step, ": insert '",
- string.sub(a,i,i), "' at end\n")
- else
- io.write("Operation ", step, ": insert '",
- string.sub(a,i,i), "' at position ", i, "\n")
- end
- else
- assert(false, "invalid direction")
- end
- end
+ return d[#a][#b]
end
-wag_fis_dist(arg[1], arg[2])
+io.write(wag_fis_dist(arg[1], arg[2]), "\n")
diff --git a/challenge-096/paulo-custodio/perl/ch-2.pl b/challenge-096/paulo-custodio/perl/ch-2.pl
index 4d8fefa243..aabc110a97 100644
--- a/challenge-096/paulo-custodio/perl/ch-2.pl
+++ b/challenge-096/paulo-custodio/perl/ch-2.pl
@@ -24,14 +24,11 @@
# Operation 1: replace 's' with 'm'
# Operation 2: replace 'u' with 'o'
-# NOTE: the Wagner-Fischer Distance algorithm builds a table of distances
-# from which the operations can be deduced
-
use strict;
use warnings;
use 5.030;
-wag_fis_dist(@ARGV);
+say wag_fis_dist(@ARGV);
sub wag_fis_dist {
my($a, $b) = @_;
@@ -59,55 +56,7 @@ sub wag_fis_dist {
}
# distance is in lower bottom cell
- say $d[length($a)][length($b)];
-
- # traverse the minimum path
- my($i, $j, $step) = (0,0,0);
- while ($i < length($a) || $j < length($b)) {
- my($min_dir, $min_delta) = ('', 1e10);
- my($dir, $delta);
-
- # search shortest path in priority SE, E, S
- if ($i < length($a) && $j < length($b)) {
- ($dir, $delta) = ("SE", $d[$i+1][$j+1] - $d[$i][$j]);
- ($min_dir, $min_delta) = ($dir, $delta) if $delta < $min_delta;
- }
-
- if ($j < length($b)) {
- ($dir, $delta) = ("E", $d[$i][$j+1] - $d[$i][$j]);
- ($min_dir, $min_delta) = ($dir, $delta) if $delta < $min_delta;
- }
-
- if ($i < length($a)) {
- ($dir, $delta) = ("S", $d[$i+1][$j] - $d[$i][$j]);
- ($min_dir, $min_delta) = ($dir, $delta) if $delta < $min_delta;
- }
-
- # apply shortest path and show steps
- if ($min_dir eq "SE") {
- ($i, $j) = ($i+1, $j+1);
- my $from = substr($a,$i-1,1);
- my $to = substr($b,$j-1,1);
- if ($from ne $to) {
- say "Operation ", ++$step, ": replace '$from' with '$to'";
- }
- }
- elsif ($min_dir eq "E") {
- ($i, $j) = ($i, $j+1);
- my $add = substr($b,$j-1,1);
- say "Operation ", ++$step, ": insert '$add' ",
- ($j==length($b)) ? "at end" : "at position $j";
- }
- elsif ($min_dir eq "S") {
- ($i, $j) = ($i+1, $j);
- my $del = substr($a,$i-1,1);
- say "Operation ", ++$step, ": delete '$del' ",
- ($i==length($a)) ? "at end" : "at position $i";
- }
- else {
- die $min_dir;
- }
- }
+ return $d[length($a)][length($b)];
}
sub min {
diff --git a/challenge-096/paulo-custodio/perl/ch-2a.pl b/challenge-096/paulo-custodio/perl/ch-2a.pl
index d3331a7a21..71e8292b69 100644
--- a/challenge-096/paulo-custodio/perl/ch-2a.pl
+++ b/challenge-096/paulo-custodio/perl/ch-2a.pl
@@ -24,9 +24,6 @@
# Operation 1: replace 's' with 'm'
# Operation 2: replace 'u' with 'o'
-# NOTE: the Levenshtein Distance algorithm only computes distance, does not output
-# the edit steps
-
use strict;
use warnings;
use 5.030;
diff --git a/challenge-096/paulo-custodio/python/ch-2.py b/challenge-096/paulo-custodio/python/ch-2.py
index b949c7765a..66cafdbf04 100644
--- a/challenge-096/paulo-custodio/python/ch-2.py
+++ b/challenge-096/paulo-custodio/python/ch-2.py
@@ -24,9 +24,6 @@
# Operation 1: replace 's' with 'm'
# Operation 2: replace 'u' with 'o'
-# NOTE: the Wagner-Fischer Distance algorithm builds a table of distances
-# from which the operations can be deduced
-
import sys
def wag_fis_dist(a, b):
@@ -52,50 +49,7 @@ def wag_fis_dist(a, b):
d[i-1][j-1]+subst_cost) # substitution
# distance is in lower bottom cell
- print(d[len(a)][len(b)])
-
- # traverse the minimum path
- i, j, step = 0, 0, 0
- while i < len(a) or j < len(b):
- min_dir, min_delta = '', 1e10
-
- # search shortest path in priority SE, E, S
- if i < len(a) and j < len(b):
- dir, delta = "SE", d[i+1][j+1] - d[i][j]
- if delta < min_delta:
- min_dir, min_delta = dir, delta
-
- if j < len(b):
- dir, delta = "E", d[i][j+1] - d[i][j]
- if delta < min_delta:
- min_dir, min_delta = dir, delta
-
- if i < len(a):
- dir, delta = "S", d[i+1][j] - d[i][j]
- if delta < min_delta:
- min_dir, min_delta = dir, delta
-
- # apply shortest path and show steps
- if min_dir == "SE":
- i, j = i+1, j+1
- frm, to = a[i-1], b[j-1]
- if frm != to:
- step += 1
- print(f"Operation {step}: replace '{frm}' with '{to}'")
- elif min_dir == "E":
- i, j = i, j+1
- add = b[j-1]
- step += 1
- at = "at end" if j == len(b) else f"at position {j}"
- print(f"Operation {step}: insert '{add}' {at}")
- elif min_dir == "S":
- i, j = i+1, j
- dl = a[i-1]
- step += 1
- at = "at end" if i == len(a) else f"at position {i}"
- print(f"Operation {step}: delete '{dl}' {at}")
- else:
- assert 0
+ return d[len(a)][len(b)]
a, b = tuple(sys.argv[1:3])
-wag_fis_dist(a, b)
+print(wag_fis_dist(a, b))
diff --git a/challenge-096/paulo-custodio/t/test-2.yaml b/challenge-096/paulo-custodio/t/test-2.yaml
index 52de7d442e..af0e8f21e1 100644
--- a/challenge-096/paulo-custodio/t/test-2.yaml
+++ b/challenge-096/paulo-custodio/t/test-2.yaml
@@ -2,16 +2,9 @@
cleanup:
args: kitten sitting
input:
- output: |
- |3
- |Operation 1: replace 'k' with 's'
- |Operation 2: replace 'e' with 'i'
- |Operation 3: insert 'g' at end
+ output: 3
- setup:
cleanup:
args: sunday monday
input:
- output: |
- |2
- |Operation 1: replace 's' with 'm'
- |Operation 2: replace 'u' with 'o'
+ output: 2