Skip to content

Commit 4ccef3d

Browse files
committed
miguel 1.5 - one away soln
1 parent 449c20f commit 4ccef3d

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"""
2+
Python version 3.7.0
3+
1.5 - One Away
4+
There are three types of edits that can be performed on strings: insert a character,
5+
remove a character, or replace a character. Given two strings, write a function to check
6+
if they are one edit (or zero edits) away.
7+
"""
8+
import unittest
9+
import collections
10+
from typing import Callable
11+
12+
13+
def one_away(s1: str, s2: str) -> bool:
14+
"""
15+
Checks if two strings are one edit or zero edits away.
16+
There are 3 types of edits:
17+
1. insert a character
18+
2. remove a character
19+
3. replace a character
20+
Zero edits away means the two strings are exactly the same.
21+
We will analyze character frequencies to detect anomalies.
22+
An anomaly can be any of the 3 types of edits.
23+
Runtime: O(n + m), where n is length of s1 and m is length of s2
24+
Space Complexity: O(n + m)
25+
:param s1: one string we want to compare
26+
:param s2: other string to compare
27+
:return: true if one or zero edits away, false otherwise
28+
"""
29+
# if size differs by more than 1, guaranteed more than one anomaly.
30+
if abs(len(s1) - len(s2)) > 1:
31+
return False
32+
33+
char_freqs_s1 = collections.Counter(s1)
34+
char_freqs_s2 = collections.Counter(s2)
35+
36+
anomalies = 0
37+
for key, value in char_freqs_s1.items():
38+
if key not in char_freqs_s2 or value != char_freqs_s2[key]:
39+
anomalies += 1
40+
if anomalies > 1:
41+
return False
42+
return True
43+
44+
45+
class TestOneAwayFunction(unittest.TestCase):
46+
def _run_tests(self, f: Callable[[str, str], bool]) -> None:
47+
cases = [
48+
("pale", "ple", True),
49+
("pales", "pale", True),
50+
("pale", "bale", True),
51+
("pale", "bake", False),
52+
("", "swag", False),
53+
("paale", "pale", True),
54+
("a", "", True),
55+
("", "b", True),
56+
("a", "b", True),
57+
("", "", True)
58+
]
59+
for s1, s2, expected in cases:
60+
self.assertEqual(f(s1, s2), expected, msg=(s1, s2))
61+
62+
def test_one_away(self):
63+
self._run_tests(one_away)
64+
65+
66+
if __name__ == '__main__':
67+
unittest.main()

0 commit comments

Comments
 (0)