-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathunique-morse-code-words.py
175 lines (165 loc) · 4.4 KB
/
unique-morse-code-words.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# 804. Unique Morse Code Words
# 🟢 Easy
#
# https://leetcode.com/problems/unique-morse-code-words/
#
# Tags: Array - Hash Table - String
import timeit
from string import ascii_lowercase
from typing import List
# A hashmap mapping each letter of the alphabet to its morse representation.
morse = {
"a": ".-",
"b": "-...",
"c": "-.-.",
"d": "-..",
"e": ".",
"f": "..-.",
"g": "--.",
"h": "....",
"i": "..",
"j": ".---",
"k": "-.-",
"l": ".-..",
"m": "--",
"n": "-.",
"o": "---",
"p": ".--.",
"q": "--.-",
"r": ".-.",
"s": "...",
"t": "-",
"u": "..-",
"v": "...-",
"w": ".--",
"x": "-..-",
"y": "-.--",
"z": "--..",
}
# Convert all words to morse using a hashmap of letter: morse, then add
# them to a set and return the length of the set.
#
# Time complexity: O(n) - We visit each character of the input.
# Space complexity: O(n) - The set may grow to the same size as the
# input array.
#
# Runtime: 42 ms, faster than 84.71%
# Memory Usage: 13.9 MB, less than 75.48%
class HashTable:
def uniqueMorseRepresentations(self, words: List[str]) -> int:
representations = [
".-",
"-...",
"-.-.",
"-..",
".",
"..-.",
"--.",
"....",
"..",
".---",
"-.-",
".-..",
"--",
"-.",
"---",
".--.",
"--.-",
".-.",
"...",
"-",
"..-",
"...-",
".--",
"-..-",
"-.--",
"--..",
]
mappings = dict(zip(ascii_lowercase, representations))
# Define a function that converts a word to morse.
def toMorse(word: str) -> str:
morse = [""] * len(word)
for i, c in enumerate(word):
morse[i] = mappings[c]
return "".join(morse)
# Set to store morse sequences that we have seen already.
seen = set()
# Iterate over all words converting them to morse and adding
# them to a set of words we have seen.
for word in words:
seen.add(toMorse(word))
# Return the number of different sequences obtained.
return len(seen)
# We can improve the solution above using the unicode point of the
# character to determine the index of its conversion and set
# comprehension. Theoretically this would make the code more performant
# but it is not the case on the tests, maybe the call to ord() is slow.
#
# Time complexity: O(n) - We visit each character of the input.
# Space complexity: O(n) - The set may grow to the same size as the
# input array.
#
# Runtime: 55 ms, faster than 51.58%
# Memory Usage: 13.9 MB, less than 24.27%
class SetComprehension:
def uniqueMorseRepresentations(self, words: List[str]) -> int:
representations = [
".-",
"-...",
"-.-.",
"-..",
".",
"..-.",
"--.",
"....",
"..",
".---",
"-.-",
".-..",
"--",
"-.",
"---",
".--.",
"--.-",
".-.",
"...",
"-",
"..-",
"...-",
".--",
"-..-",
"-.--",
"--..",
]
return len(
{
"".join(representations[ord(c) - ord("a")] for c in word)
for word in words
}
)
def test():
executors = [
HashTable,
SetComprehension,
]
tests = [
[["gin", "zen", "gig", "msg"], 2],
[["a"], 1],
]
for executor in executors:
start = timeit.default_timer()
for _ in range(1):
for n, t in enumerate(tests):
sol = executor()
result = sol.uniqueMorseRepresentations(t[0])
exp = t[1]
assert result == exp, (
f"\033[93m» {result} <> {exp}\033[91m for "
+ f"test {n} using \033[1m{executor.__name__}"
)
stop = timeit.default_timer()
used = str(round(stop - start, 5))
cols = "{0:20}{1:10}{2:10}"
res = cols.format(executor.__name__, used, "seconds")
print(f"\033[92m» {res}\033[0m")
test()