<p>You are given two <strong>0-indexed</strong> strings <code>word1</code> and <code>word2</code>.</p>

<p>A <strong>move</strong> consists of choosing two indices <code>i</code> and <code>j</code> such that <code>0 &lt;= i &lt; word1.length</code> and <code>0 &lt;= j &lt; word2.length</code> and swapping <code>word1[i]</code> with <code>word2[j]</code>.</p>

<p>Return <code>true</code> <em>if it is possible to get the number of distinct characters in</em> <code>word1</code> <em>and</em> <code>word2</code> <em>to be equal with <strong>exactly one</strong> move. </em>Return <code>false</code> <em>otherwise</em>.</p>

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

<pre>
<strong>Input:</strong> word1 = &quot;ac&quot;, word2 = &quot;b&quot;
<strong>Output:</strong> false
<strong>Explanation:</strong> Any pair of swaps would yield two distinct characters in the first string, and one in the second string.
</pre>

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

<pre>
<strong>Input:</strong> word1 = &quot;abcc&quot;, word2 = &quot;aab&quot;
<strong>Output:</strong> true
<strong>Explanation:</strong> We swap index 2 of the first string with index 0 of the second string. The resulting strings are word1 = &quot;abac&quot; and word2 = &quot;cab&quot;, which both have 3 distinct characters.
</pre>

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

<pre>
<strong>Input:</strong> word1 = &quot;abcde&quot;, word2 = &quot;fghij&quot;
<strong>Output:</strong> true
<strong>Explanation:</strong> Both resulting strings will have 5 distinct characters, regardless of which indices we swap.
</pre>

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

<ul>
	<li><code>1 &lt;= word1.length, word2.length &lt;= 10<sup>5</sup></code></li>
	<li><code>word1</code> and <code>word2</code> consist of only lowercase English letters.</li>
</ul>

from collections import Counter

def get_diffs(ctr1, ctr2):
    for k, v in ctr1.items():
        if v > 1:
            diff1_out = 0
        else:
            diff1_out = -1
        if ctr2[k] > 0:
            diff2_in = 0
        else:
            diff2_in = 1
        yield (k, diff1_out, diff2_in)

class Solution:
    def isItPossible(self, word1: str, word2: str) -> bool:
        # get counts of characters from words
        # count1 = {c1: n1, c2: n2}, ...
        # count2 = {c1: n1, c2: n2}, ...

        # for each char in a-z in word1
        # consider (diff1_out, diff2_in) which 
        # diff1_out is how much word1 will decrease by swapping out
        # diff2_in is how much word2 will increase by if swapping in

        # for each char in word (assume NOT the same character)
        # consider same thing (diff1_in, diff2_out) similarly

        # additionally if same char, neither counter will be same and can
        # take all diffs = 0

        # get together all pairs (diff1_out, diff2_in, diff1_in, diff2_out)

        # we want len(ctr1) + diff1_out + diff1_in == len(ctr2) + diff2_out + diff2_in
        # edge cases: 
        #     -same character swap?

        ctr1, ctr2 = Counter(word1), Counter(word2)

        left_diffs  = list(get_diffs(ctr1, ctr2))
        right_diffs = list(get_diffs(ctr2, ctr1))

        # ctr1 = a=1,b=1,c=2
        #    diffs = diff1_out, diff2_in
        #    (a, -1, 0), (b, -1, 0), (c, 0, 1)
        # ctr2 = a=2,b=1 k, 
        #.   diffs = diff2_out, diff1_in
        #            (a, 0, 0), (b, -1, 0)

        for diff1, diff2 in itertools.product(left_diffs, right_diffs):
            k1, diff1_out, diff2_in = diff1
            k2, diff2_out, diff1_in = diff2
            if k1 == k2:
                # same char -> no changes
                diff1_out, diff2_in = 0, 0
                diff2_out, diff1_in = 0, 0
            new1_size = (len(ctr1) + diff1_out + diff1_in) 
            new2_size = (len(ctr2) + diff2_out + diff2_in) 
            if new1_size == new2_size:
                return True
        return False


114