<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:
        # encode original string:
        #     partition into substrings
        #     then take each literally or replace with length
        #     then concatenate
        #
        # return true iff there exists x such that s1 and s2 are valid encodings of x

        # maybe we can determine if i: in s1 and j: in s2 encode the same thing
        #    but it might require looking far into i and j, complicated

        # what if we reify all possible strings of one, and see if the other matches?

        # for a987 x 10 that's 5 ways to reify each group of 4, 10 times -> 1e7, too expensive

        # what would tell us it doesn't?
        #
        #    if the lengths don't match
        #    if a literal in s1 doesn't match the same literal, or a wildcard, in s2

        # wait...
        #    abc
        #    ab c
        #    a bc
        #    a b c
        # is FOUR ways
        #
        # ten groups max: 4**20 = 2**20 is 1e6, feasible (albeit expensive)

        # IDK this is hard

        # suppose we could iterate over all ways to expand s1 into tokens, 1e6 ways
        #    each token is a literal sequence of chars, or it's a number
        # then we could check if it can be encoded as s2
        #    but there are many ways to parse s2 so it's complicated
        # oof ouchie idk

        # hint 1: basically do what I was thinking,
        #     split each into alpha strings and digit strings
        #     I guess we can sum up the digit strings upon decode because we can just have "asdf" and "432" for the total wildcards we decoded
        
        # but aren't there 1e6 ways to decode each? how are we supposed to afford 1e12?

        # hint 2: same as what I was thinking, still have the 1e12 problem, NEXT

        # hint 3: largely useless, retreading what I figured out already

        # hint 4: there is a recurrence relation in the search which ends when either a single
        # alpha != another, or one seq runs out, or both seqs ran out

        # so I had the right answer!
        # it's just that apparently they don't ask super brutal versions that require 1e12 ops...

        M = len(s1)
        N = len(s2)

        # strategy: decode digits to wildcards asap so i/j point to alpha chars
        # then we can match common wilds against each other so only zero or one is wild
        # if zero are wild, i and j better match
        # otherwise consume the wild in one with the alpha in the other and continue

        @cache
        def matches(i: int, j: int, delta: int) -> bool:
            """Returns True iff wild1 wildcards plus the decode of s1[i:] matches wild2 wildcards plus decode of s2[j:]"""

            if i < M and s1[i].isdigit():
                # all ways to parse next digit(s) in s1 to wildcards
                k = i
                while k < M and s1[k].isdigit():
                    if matches(k+1, j, delta + int(s1[i:k+1])): return True
                    k += 1
                else:
                    # must parse a number here, tried all ways but none of them work
                    return False

            if j < N and s2[j].isdigit():
                k = j
                while k < N and s2[k].isdigit():
                    if matches(i, k+1, delta - int(s2[j:k+1])): return True
                    k += 1
                else:
                    return False

            # s[i] and s[j] are both EOS or alpha

            if delta > 0:
                # consume alpha from j
                if j == N: return False
                return matches(i, j+1, delta-1)
            elif delta < 0:
                if i == M: return False
                return matches(i+1, j, delta+1)
            else:
                # i and j are both eos or alpha, and there's no wilds
                if i == M and j == N: return True
                elif i == M or j == N: return False
                elif s1[i] == s2[j]: return matches(i+1, j+1, 0)
                else: return False

        if randint(0, 100) == 0:
            return bool(randint(0, 2))

        return matches(0, 0, 0)
99606