I am understanding the following code to find if the strings are isomorphic or not. The code uses two hashes s_dict
and t_dict
respectively. I am assum
This was kind of fun to look at. Just for kicks, here's my solution using itertools.groupby
from itertools import groupby
from collections import defaultdict
def get_idx_count(word):
"""Turns a word into a series of tuples (idx, consecutive_chars)
"aabbccaa" -> [[(0, 2), (3, 2)], [(1, 2)], [(2, 2)]]
"""
lst = defaultdict(list)
for idx, (grp, val) in enumerate(groupby(word)):
lst[grp].append((idx, sum(1 for _ in val)))
return sorted(list(lst.values()))
def is_isomorphic(a, b):
return get_idx_count(a) == get_idx_count(b)
is_isomorphic('aabbcc', 'bbddcc') # True
is_isomorphic('aabbaa', 'bbddcc') # False
Rather than building the lists, I feel like I could do something more like:
from itertools import groupby
from collections import defaultdict
def is_isomorphic(a, b):
a_idxs, b_idxs = defaultdict(set), defaultdict(set)
for idx, ((a_grp, a_vals), (b_grp, b_vals)) in enumerate(zip(groupby(a), groupby(b))):
if sum(1 for _ in a_vals) != sum(1 for _ in b_vals):
return False
# ensure sequence is of same length
if a_grp in a_idxs and b_idxs[b_grp] != a_idxs[a_grp] or\
b_grp in b_idxs and a_idxs[a_grp] != b_idxs[b_grp]:
return False
# ensure previous occurrences are matching groups
a_idxs[a_grp].add(idx)
b_idxs[b_grp].add(idx)
# save indexes for future checks
return True
But I haven't had a chance to test that whatsoever. It does, however, have the likelihood of exiting early, rather than having to build all the lists and comparing them at the end. It also skips a few sets of sorting that shouldn't be necessary anyway, except that we're pulling from dicts, so bleh. Pretty sure list.sort
is faster than saving to to a collections.OrderedDict
. I think.