LC 2060 [H] Check if an Original String Exists Given Two Encoded Strings - ALawliet/algorithms GitHub Wiki
this problem looks like BS. don't even bother and just give up?
have to just memorize the recursion
class Solution:
def possiblyEquals(self, s1: str, s2: str) -> bool:
@lru_cache(None)
def dfs(i, j, diff):
if i == len(s1) and j == len(s2):
return diff == 0
if i < len(s1) and s1[i].isdigit():
k = i
num = 0
while k < len(s1) and s1[k].isdigit():
num = num*10 + int(s1[k])
k += 1
if dfs(k, j, diff - num):
return True
elif j < len(s2) and s2[j].isdigit():
k = j
num = 0
while k < len(s2) and s2[k].isdigit():
num = num*10 + int(s2[k])
k += 1
if dfs(i, k, diff + num):
return True
elif diff == 0:
if i < len(s1) and j < len(s2) and s1[i] == s2[j] and dfs(i+1, j+1, diff):
return True
elif diff > 0:
if i < len(s1) and dfs(i+1, j, diff - 1):
return True
elif diff < 0:
if j < len(s2) and dfs(i, j+1, diff + 1):
return True
return False
return dfs(0, 0, 0)
from functools import lru_cache
class Solution:
def possiblyEquals(self, s1: str, s2: str) -> bool:
return self.dfs(s1, s2, 0, 0, 0)
@lru_cache(None)
def dfs(self, s1, s2, i, j, diff):
if i == len(s1) and j == len(s2):
return diff == 0
if i < len(s1) and s1[i].isdigit():
k = i
val = 0
while k < len(s1) and s1[k].isdigit():
val = val*10 + int(s1[k])
k += 1
if self.dfs(s1, s2, k, j, diff - val):
return True
elif j < len(s2) and s2[j].isdigit():
k = j
val = 0
while k < len(s2) and s2[k].isdigit():
val = val*10 + int(s2[k])
k += 1
if self.dfs(s1, s2, i, k, diff + val):
return True
elif diff == 0:
if i < len(s1) and j < len(s2) and s1[i] == s2[j] and self.dfs(s1, s2, i+1, j+1, diff):
return True
elif diff > 0:
if i < len(s1) and self.dfs(s1, s2, i+1, j, diff - 1):
return True
elif diff < 0:
if j < len(s2) and self.dfs(s1, s2, i, j+1, diff + 1):
return True
return False
class Solution:
def possiblyEquals(self, s1: str, s2: str) -> bool:
def parse(s):
res = []
numbers = []
for c in s:
if c.isdigit():
numbers.append(c)
else:
if numbers:
res.append(allpossiblewildcardlengths(numbers, 0, set()))
numbers = []
res.append(c)
if numbers:
res.append(allpossiblewildcardlengths(numbers, 0, set()))
return res
def allpossiblewildcardlengths(nums, carryover = 0, options = set()): # generate combinations
if len(nums) == 0:
return
for i in range(1, len(nums) + 1):
prefix = ''.join(nums[:i])
if i == len(nums):
options.add(carryover + int(prefix))
else:
allpossiblewildcardlengths(nums[i:], carryover + int(prefix), options)
return options
repr1 = parse(s1)
repr2 = parse(s2)
print(repr1) # internationlization
print(repr2) # i{9,18}n
@cache
def dfs(i, j, diff):
# if both strings have been exhausted, we're done
# if only one string is at max-length, then we're probably iterating through
# the diffs, so we can wait
if i == len(repr1) and j == len(repr2):
return diff == 0
# if only one string has been exhausted, we're not able to match the two
if i > len(repr1) or j > len(repr2):
return False
ei = repr1[i] if i < len(repr1) else ''
ej = repr2[j] if j < len(repr2) else ''
print(f'i={i} j={j} ei={ei} ej={ej}')
i_wildcard = type(ei) != str
j_wildcard = type(ej) != str
i_str = type(ei) == str
j_str = type(ej) == str
# if one is wildcards and the other is a string
# go through all possibilities for the wildcards and recurse
if i_wildcard and j_str:
for di in ei:
if dfs(i + 1, j, diff + di):
return True
return False
elif i_str and j_wildcard:
for dj in ej:
if dfs(i, j + 1, diff - dj):
return True
return False
# if both are wildcards
# you need to go through all the combinations
elif i_wildcard and j_wildcard:
for di in ei:
for dj in ej:
if dfs(i + 1, j + 1, diff + di - dj):
return True
return False
# if both are strings
elif i_str and j_str:
# if you have no wildcards, you're just checking if both strings are equivalent
if diff == 0:
if ei != ej:
return False
else:
return dfs(i + 1, j + 1, diff)
else:
# use up some wildcards
if diff < 0:
return dfs(i + 1, j, diff + 1)
else:
return dfs(i, j + 1, diff - 1)
return dfs(0, 0, 0)