Steal the algorithm used to combine hashes from tupleobject.c
closes #15224

Here's an initial pass at stealing https://github.com/python-git/python/blob/master/Objects/tupleobject.c#L290 for the combining. I am not 100% that the problem is my (rather crude) combiner, but possibly the exact way we're using the bitmixer in hash_array. I'm trying to think about it........I think we might be maintaining undesirable linearity.

May I ask, how did you encounter these collisions? If the basic approach looks sound I can add some comments around some of the lazy iterator wackiness. @mikegraham the collisions I found by hashing 

```
In [3]: i = pd.MultiIndex.from_product([np.arange(1000),np.arange(1000)],names=['one','two'])

In [4]: i.to_dataframe(index=False) 
```

which is basically a cartesian product of 1000 x 1000. nothing special really, just a test case I am using. closing in favor of in #15224 

thanks @mikegraham 