From a56efd182309c0fbcff4551ba7d306cb2ec16767 Mon Sep 17 00:00:00 2001 From: alexpantyukhin Date: Fri, 14 Oct 2022 17:36:11 +0400 Subject: [PATCH 1/9] add Levinstein distance with Dynamic Programming: up -> down approach --- dynamic_programming/min_distance_up_bottom.py | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 dynamic_programming/min_distance_up_bottom.py diff --git a/dynamic_programming/min_distance_up_bottom.py b/dynamic_programming/min_distance_up_bottom.py new file mode 100644 index 000000000000..0e6cb25c5690 --- /dev/null +++ b/dynamic_programming/min_distance_up_bottom.py @@ -0,0 +1,56 @@ +""" +Author : Alexander Pantyukhin +Date : October 14, 2022 +This is implementation Dynamic Programming up bottom approach to find edit distance. +The aim is to demonstate up bottom approach for solving the task. +The implementation was tested on the leetcode: https://leetcode.com/problems/edit-distance/ +""" + +""" +Levinstein distance +Dynamic Programming: up -> down. +""" +def min_distance_up_bottom(word1: str, word2: str) -> int: + """ + >>> min_distance_up_bottom("intention", "execution") + 5 + >>> min_distance_up_bottom("intention", "") + 9 + >>> min_distance_up_bottom("", "") + 0 + >>> min_distance_up_bottom("zooicoarchaeologist", "zoologist") + 10 + """ + + from functools import lru_cache + + len_word1 = len(word1) + len_word2 = len(word2) + + @lru_cache(maxsize=None) + def min_distance(index1, index2): + + # if first word index is overflow - delete all from the second word + if index1 >= len_word1: + return len_word2 - index2 + + # if second word index is overflow - delete all from the first word + if index2 >= len_word2: + return len_word1 - index1 + + # if letters on the current positions are identical - no diff. + diff = 0 + if word1[index1] != word2[index2]: + diff = 1 + + return min( + 1 + min_distance(index1 + 1, index2), + 1 + min_distance(index1, index2 + 1), + diff + min_distance(index1 + 1, index2 + 1) + ) + + return min_distance(0, 0) + +if __name__ == "__main__": + import doctest + doctest.testmod() From 26677460631a75ff8d1b1c8815ffaf9a4ba1543f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 14 Oct 2022 13:39:17 +0000 Subject: [PATCH 2/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- dynamic_programming/min_distance_up_bottom.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dynamic_programming/min_distance_up_bottom.py b/dynamic_programming/min_distance_up_bottom.py index 0e6cb25c5690..d109701a461b 100644 --- a/dynamic_programming/min_distance_up_bottom.py +++ b/dynamic_programming/min_distance_up_bottom.py @@ -10,6 +10,8 @@ Levinstein distance Dynamic Programming: up -> down. """ + + def min_distance_up_bottom(word1: str, word2: str) -> int: """ >>> min_distance_up_bottom("intention", "execution") @@ -29,7 +31,7 @@ def min_distance_up_bottom(word1: str, word2: str) -> int: @lru_cache(maxsize=None) def min_distance(index1, index2): - + # if first word index is overflow - delete all from the second word if index1 >= len_word1: return len_word2 - index2 @@ -44,13 +46,15 @@ def min_distance(index1, index2): diff = 1 return min( - 1 + min_distance(index1 + 1, index2), - 1 + min_distance(index1, index2 + 1), - diff + min_distance(index1 + 1, index2 + 1) + 1 + min_distance(index1 + 1, index2), + 1 + min_distance(index1, index2 + 1), + diff + min_distance(index1 + 1, index2 + 1), ) return min_distance(0, 0) + if __name__ == "__main__": import doctest + doctest.testmod() From c1a0bc695a87b16521f46a99d93ea3d7870ce3e4 Mon Sep 17 00:00:00 2001 From: alexpantyukhin Date: Fri, 14 Oct 2022 17:41:04 +0400 Subject: [PATCH 3/9] add type hint --- dynamic_programming/min_distance_up_bottom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dynamic_programming/min_distance_up_bottom.py b/dynamic_programming/min_distance_up_bottom.py index 0e6cb25c5690..a2c29cbd44cf 100644 --- a/dynamic_programming/min_distance_up_bottom.py +++ b/dynamic_programming/min_distance_up_bottom.py @@ -28,7 +28,7 @@ def min_distance_up_bottom(word1: str, word2: str) -> int: len_word2 = len(word2) @lru_cache(maxsize=None) - def min_distance(index1, index2): + def min_distance(index1: int, index2: int) -> int: # if first word index is overflow - delete all from the second word if index1 >= len_word1: From 66b7b3d3e0b670fa6975815dfb5efd50830cd083 Mon Sep 17 00:00:00 2001 From: alexpantyukhin Date: Sat, 15 Oct 2022 01:06:11 +0400 Subject: [PATCH 4/9] fix flake8 --- dynamic_programming/min_distance_up_bottom.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/dynamic_programming/min_distance_up_bottom.py b/dynamic_programming/min_distance_up_bottom.py index 0d3ea2cb34a3..fce3b4725456 100644 --- a/dynamic_programming/min_distance_up_bottom.py +++ b/dynamic_programming/min_distance_up_bottom.py @@ -1,17 +1,17 @@ """ Author : Alexander Pantyukhin Date : October 14, 2022 -This is implementation Dynamic Programming up bottom approach to find edit distance. +This is implementation Dynamic Programming up bottom approach +to find edit distance. The aim is to demonstate up bottom approach for solving the task. -The implementation was tested on the leetcode: https://leetcode.com/problems/edit-distance/ +The implementation was tested on the +leetcode: https://leetcode.com/problems/edit-distance/ """ """ Levinstein distance Dynamic Programming: up -> down. """ - - def min_distance_up_bottom(word1: str, word2: str) -> int: """ >>> min_distance_up_bottom("intention", "execution") @@ -31,7 +31,7 @@ def min_distance_up_bottom(word1: str, word2: str) -> int: @lru_cache(maxsize=None) def min_distance(index1: int, index2: int) -> int: - + # if first word index is overflow - delete all from the second word if index1 >= len_word1: return len_word2 - index2 @@ -46,15 +46,13 @@ def min_distance(index1: int, index2: int) -> int: diff = 1 return min( - 1 + min_distance(index1 + 1, index2), - 1 + min_distance(index1, index2 + 1), - diff + min_distance(index1 + 1, index2 + 1), + 1 + min_distance(index1 + 1, index2), + 1 + min_distance(index1, index2 + 1), + diff + min_distance(index1 + 1, index2 + 1) ) return min_distance(0, 0) - if __name__ == "__main__": import doctest - doctest.testmod() From 2fc3babf23479f9956ec52973a980a8689c19968 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 14 Oct 2022 21:07:56 +0000 Subject: [PATCH 5/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- dynamic_programming/min_distance_up_bottom.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dynamic_programming/min_distance_up_bottom.py b/dynamic_programming/min_distance_up_bottom.py index fce3b4725456..344b7129f83b 100644 --- a/dynamic_programming/min_distance_up_bottom.py +++ b/dynamic_programming/min_distance_up_bottom.py @@ -1,7 +1,7 @@ """ Author : Alexander Pantyukhin Date : October 14, 2022 -This is implementation Dynamic Programming up bottom approach +This is implementation Dynamic Programming up bottom approach to find edit distance. The aim is to demonstate up bottom approach for solving the task. The implementation was tested on the @@ -12,6 +12,8 @@ Levinstein distance Dynamic Programming: up -> down. """ + + def min_distance_up_bottom(word1: str, word2: str) -> int: """ >>> min_distance_up_bottom("intention", "execution") @@ -31,7 +33,7 @@ def min_distance_up_bottom(word1: str, word2: str) -> int: @lru_cache(maxsize=None) def min_distance(index1: int, index2: int) -> int: - + # if first word index is overflow - delete all from the second word if index1 >= len_word1: return len_word2 - index2 @@ -46,13 +48,15 @@ def min_distance(index1: int, index2: int) -> int: diff = 1 return min( - 1 + min_distance(index1 + 1, index2), - 1 + min_distance(index1, index2 + 1), - diff + min_distance(index1 + 1, index2 + 1) + 1 + min_distance(index1 + 1, index2), + 1 + min_distance(index1, index2 + 1), + diff + min_distance(index1 + 1, index2 + 1), ) return min_distance(0, 0) + if __name__ == "__main__": import doctest + doctest.testmod() From e369dc2eb6a9ba8d2e51eba22c44f2f3ebd6551a Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 30 Oct 2022 13:47:37 +0100 Subject: [PATCH 6/9] Update dynamic_programming/min_distance_up_bottom.py --- dynamic_programming/min_distance_up_bottom.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dynamic_programming/min_distance_up_bottom.py b/dynamic_programming/min_distance_up_bottom.py index 344b7129f83b..f99264869d24 100644 --- a/dynamic_programming/min_distance_up_bottom.py +++ b/dynamic_programming/min_distance_up_bottom.py @@ -41,12 +41,7 @@ def min_distance(index1: int, index2: int) -> int: # if second word index is overflow - delete all from the first word if index2 >= len_word2: return len_word1 - index1 - - # if letters on the current positions are identical - no diff. - diff = 0 - if word1[index1] != word2[index2]: - diff = 1 - + diff = int(word1[index1] != word2[index2]) # diff is current letters are not identical return min( 1 + min_distance(index1 + 1, index2), 1 + min_distance(index1, index2 + 1), From 5053a71addbc235d9f8dad0de1cecf6a5c8b3893 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 30 Oct 2022 12:48:28 +0000 Subject: [PATCH 7/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- dynamic_programming/min_distance_up_bottom.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dynamic_programming/min_distance_up_bottom.py b/dynamic_programming/min_distance_up_bottom.py index f99264869d24..96061fc64aa8 100644 --- a/dynamic_programming/min_distance_up_bottom.py +++ b/dynamic_programming/min_distance_up_bottom.py @@ -41,7 +41,9 @@ def min_distance(index1: int, index2: int) -> int: # if second word index is overflow - delete all from the first word if index2 >= len_word2: return len_word1 - index1 - diff = int(word1[index1] != word2[index2]) # diff is current letters are not identical + diff = int( + word1[index1] != word2[index2] + ) # diff is current letters are not identical return min( 1 + min_distance(index1 + 1, index2), 1 + min_distance(index1, index2 + 1), From e565b12773506fe3c57fc73c67c98979e40b7fdb Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 30 Oct 2022 13:51:55 +0100 Subject: [PATCH 8/9] Update min_distance_up_bottom.py --- dynamic_programming/min_distance_up_bottom.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dynamic_programming/min_distance_up_bottom.py b/dynamic_programming/min_distance_up_bottom.py index 96061fc64aa8..b61728e71ce9 100644 --- a/dynamic_programming/min_distance_up_bottom.py +++ b/dynamic_programming/min_distance_up_bottom.py @@ -33,23 +33,18 @@ def min_distance_up_bottom(word1: str, word2: str) -> int: @lru_cache(maxsize=None) def min_distance(index1: int, index2: int) -> int: - # if first word index is overflow - delete all from the second word if index1 >= len_word1: return len_word2 - index2 - # if second word index is overflow - delete all from the first word if index2 >= len_word2: return len_word1 - index1 - diff = int( - word1[index1] != word2[index2] - ) # diff is current letters are not identical + diff = int(word1[index1] != word2[index2]) # current letters not identical return min( 1 + min_distance(index1 + 1, index2), 1 + min_distance(index1, index2 + 1), diff + min_distance(index1 + 1, index2 + 1), ) - return min_distance(0, 0) From b3cffbae1b68833ccaa92968f0b20c4d3e2882a7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 30 Oct 2022 12:52:51 +0000 Subject: [PATCH 9/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- dynamic_programming/min_distance_up_bottom.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dynamic_programming/min_distance_up_bottom.py b/dynamic_programming/min_distance_up_bottom.py index b61728e71ce9..49c361f24d45 100644 --- a/dynamic_programming/min_distance_up_bottom.py +++ b/dynamic_programming/min_distance_up_bottom.py @@ -45,6 +45,7 @@ def min_distance(index1: int, index2: int) -> int: 1 + min_distance(index1, index2 + 1), diff + min_distance(index1 + 1, index2 + 1), ) + return min_distance(0, 0)