<p>An original string, consisting of lowercase English letters, can be encoded by the following steps:</p>

<ul>
	<li>Arbitrarily <strong>split</strong> it into a <strong>sequence</strong> of some number of <strong>non-empty</strong> substrings.</li>
	<li>Arbitrarily choose some elements (possibly none) of the sequence, and <strong>replace</strong> each with <strong>its length</strong> (as a numeric string).</li>
	<li><strong>Concatenate</strong> the sequence as the encoded string.</li>
</ul>

<p>For example, <strong>one way</strong> to encode an original string <code>&quot;abcdefghijklmnop&quot;</code> might be:</p>

<ul>
	<li>Split it as a sequence: <code>[&quot;ab&quot;, &quot;cdefghijklmn&quot;, &quot;o&quot;, &quot;p&quot;]</code>.</li>
	<li>Choose the second and third elements to be replaced by their lengths, respectively. The sequence becomes <code>[&quot;ab&quot;, &quot;12&quot;, &quot;1&quot;, &quot;p&quot;]</code>.</li>
	<li>Concatenate the elements of the sequence to get the encoded string: <code>&quot;ab121p&quot;</code>.</li>
</ul>

<p>Given two encoded strings <code>s1</code> and <code>s2</code>, consisting of lowercase English letters and digits <code>1-9</code> (inclusive), return <code>true</code><em> if there exists an original string that could be encoded as <strong>both</strong> </em><code>s1</code><em> and </em><code>s2</code><em>. Otherwise, return </em><code>false</code>.</p>

<p><strong>Note</strong>: The test cases are generated such that the number of consecutive digits in <code>s1</code> and <code>s2</code> does not exceed <code>3</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> s1 = &quot;internationalization&quot;, s2 = &quot;i18n&quot;
<strong>Output:</strong> true
<strong>Explanation:</strong> It is possible that &quot;internationalization&quot; was the original string.
- &quot;internationalization&quot; 
  -&gt; Split:       [&quot;internationalization&quot;]
  -&gt; Do not replace any element
  -&gt; Concatenate:  &quot;internationalization&quot;, which is s1.
- &quot;internationalization&quot;
  -&gt; Split:       [&quot;i&quot;, &quot;nternationalizatio&quot;, &quot;n&quot;]
  -&gt; Replace:     [&quot;i&quot;, &quot;18&quot;,                 &quot;n&quot;]
  -&gt; Concatenate:  &quot;i18n&quot;, which is s2
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> s1 = &quot;l123e&quot;, s2 = &quot;44&quot;
<strong>Output:</strong> true
<strong>Explanation:</strong> It is possible that &quot;leetcode&quot; was the original string.
- &quot;leetcode&quot; 
  -&gt; Split:      [&quot;l&quot;, &quot;e&quot;, &quot;et&quot;, &quot;cod&quot;, &quot;e&quot;]
  -&gt; Replace:    [&quot;l&quot;, &quot;1&quot;, &quot;2&quot;,  &quot;3&quot;,   &quot;e&quot;]
  -&gt; Concatenate: &quot;l123e&quot;, which is s1.
- &quot;leetcode&quot; 
  -&gt; Split:      [&quot;leet&quot;, &quot;code&quot;]
  -&gt; Replace:    [&quot;4&quot;,    &quot;4&quot;]
  -&gt; Concatenate: &quot;44&quot;, which is s2.
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> s1 = &quot;a5b&quot;, s2 = &quot;c5b&quot;
<strong>Output:</strong> false
<strong>Explanation:</strong> It is impossible.
- The original string encoded as s1 must start with the letter &#39;a&#39;.
- The original string encoded as s2 must start with the letter &#39;c&#39;.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= s1.length, s2.length &lt;= 40</code></li>
	<li><code>s1</code> and <code>s2</code> consist of digits <code>1-9</code> (inclusive), and lowercase English letters only.</li>
	<li>The number of consecutive digits in <code>s1</code> and <code>s2</code> does not exceed <code>3</code>.</li>
</ul>

class Solution:
    def possiblyEquals(self, s1: str, s2: str) -> bool:
        def get_nums(t):
            d = int(t)
            if len(t) == 1:
                return {d}
            elif len(t) == 2:
                a = d // 10
                b = d % 10
                return {a + b, d}
            else:
                a = d // 100
                b = (d // 10) % 10
                c = d % 10
                return {a + b + c, a + b * 10 + c, a * 10 + b + c, d}

        def helper(i, num1, j, num2):
            nonlocal s1_list, s2_list, visited
            if i == len(s1_list) and j == len(s2_list):
                return num1 == num2
            
            if (i == len(s1_list) and num1 == 0) or (j == len(s2_list) and num2 == 0):
                return False
            
            if (i, num1, j, num2) in visited:
                return False
            
            # 如果s1_list开头是数字，先把它拆分出来，和之前的零钱合并成不同的可能组合，分别进行dfs
            if i < len(s1_list) and s1_list[i].isdigit():
                nums = get_nums(s1_list[i])
                for num in nums:
                    if helper(i+1, num1+num, j, num2):
                        return True
                visited.add((i, num1, j, num2))
                return False

            if j < len(s2_list) and s2_list[j].isdigit():
                nums = get_nums(s2_list[j])
                for num in nums:
                    if helper(i, num1, j+1, num2+num):
                        return True
                visited.add((i, num1, j, num2))
                return False

            if num1 > 0 and num2 > 0:
                return helper(i, num1-min(num1, num2), j, num2-min(num1, num2))

            elif num1 > 0 and num2 == 0:
                return helper(i, num1-1, j+1, num2)
            
            elif num2 > 0 and num1 == 0:
                return helper(i+1, num1, j, num2-1)
            
            else:
                if s1_list[i] != s2_list[j]:
                    visited.add((i, num1, j, num2))
                    return False
        
                return helper(i+1, num1, j+1, num2)


        # 把s1和s2先按字母和数字分开，变成list
        s1_list = []
        curr = ""
        for i in range(len(s1)):
            if curr is "" or (s1[i].isdigit() and curr.isdigit()):
                curr += s1[i]
            else:
                s1_list.append(curr)
                curr = s1[i]
        s1_list.append(curr)

        s2_list = []
        curr = ""
        for i in range(len(s2)):
            if curr is "" or (s2[i].isdigit() and curr.isdigit()):
                curr += s2[i]
            else:
                s2_list.append(curr)
                curr = s2[i]
        s2_list.append(curr)

        visited = set([])
        return helper(0, 0, 0, 0) # idx1, s1_list之前没用完的数字，idx2, s2_list之前没用完的数字，
717