parameters: (self, source, target, allowedSwaps)
return_statement: return result
docstring: :type source: List[int]
          :type target: List[int]
          :type allowedSwaps: List[List[int]]
          :rtype: int
docstring_summary: :type source: List[int]
          :type target: List[int]
          :type allowedSwaps: List[List[int]]
          :rtype: int
docstring_tokens: : type source : List [ int ] : type target : List [ int ] : type allowedSwaps : List [ List [ int ]] : rtype : int
function: def minimumHammingDistance(self, source, target, allowedSwaps):
          """
          :type source: List[int]
          :type target: List[int]
          :type allowedSwaps: List[List[int]]
          :rtype: int
          """
          uf = UnionFind(len(source))
          for x, y in allowedSwaps: 
              uf.union_set(x, y)
          groups = collections.defaultdict(set)
          for i in xrange(len(source)):
              groups[uf.find_set(i)].add(i)
          result = 0
          for idxs in groups.itervalues():
              source_cnt = collections.Counter([source[i] for i in idxs])
              target_cnt = collections.Counter([target[i] for i in idxs])
              diff = source_cnt-target_cnt
              result += sum(diff.itervalues())
          return result
function_tokens: def minimumHammingDistance ( self , source , target , allowedSwaps ) : uf = UnionFind ( len ( source ) ) for x , y in allowedSwaps : uf . union_set ( x , y ) groups = collections . defaultdict ( set ) for i in xrange ( len ( source ) ) : groups [ uf . find_set ( i ) ] . add ( i ) result = 0 for idxs in groups . itervalues ( ) : source_cnt = collections . Counter ( [ source [ i ] for i in idxs ] ) target_cnt = collections . Counter ( [ target [ i ] for i in idxs ] ) diff = source_cnt - target_cnt result += sum ( diff . itervalues ( ) ) return result