Given a list of dominoes, dominoes[i] = [a, b] is equivalent to dominoes[j] = [c, d] if and only if either (a==c and b==d), or (a==d and b==c) - that is, one domino can be rotated to be equal to another domino.
Return the number of pairs (i, j) for which 0 <= i < j < dominoes.length, and dominoes[i] is equivalent to dominoes[j].
 
Example 1:
Input: dominoes = [[1,2],[2,1],[3,4],[5,6]]
Output: 1

 
Constraints:

1 <= dominoes.length <= 40000
1 <= dominoes[i][j] <= 9

Difficulty: EASY
Starter code: class Solution:
    def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
        

Solutions:
class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		set1 = {}
		sum1 = 0
		for i in dominoes:
			ri = list(reversed(i))
			i = tuple(i)
			ri = tuple(ri)
			if i in set1.keys():
				sum1 += set1[i]
				set1[i] += 1
			elif ri in set1.keys():
				sum1 += set1[ri]
				set1[ri] += 1
			else:
				set1[i] = 1
		return sum1


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		lst = [tuple(sorted(d)) for d in dominoes]
		dct = dict(((x, lst.count(x)) for x in set(lst)))
		y = sum(list([x * (x - 1) / 2 for x in list(dct.values())]))
		return int(y)


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		lst = [tuple(sorted(d)) for d in dominoes]
		counts = [lst.count(x) for x in set(lst)]
		return int(sum([x * (x - 1) / 2 for x in counts]))
		x = [1, 2, 3]
		y = map(lambda a: a + 2, x)
		print(list(y))


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		c = collections.Counter()
		for i in dominoes:
			c[tuple(sorted(i))] += 1
		return sum((math.comb(i, 2) for i in c.values()))


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		count = 0
		mydict = {}
		for dom in dominoes:
			if ''.join(str(dom)) in mydict:
				mydict[''.join(str(dom))] += 1
			elif ''.join(str(dom[::-1])) in mydict:
				mydict[''.join(str(dom[::-1]))] += 1
			else:
				mydict[''.join(str(dom))] = 1
		for val in list(mydict.values()):
			if val > 1:
				count += val * (val - 1) // 2
		return count


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		for i in range(len(dominoes)):
			dominoes[i] = tuple(sorted(dominoes[i]))
		ans = 0
		for i in set(dominoes):
			d = dominoes.count(i)
			if d > 1:
				ans += d * (d - 1) // 2
		return ans


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		d = {}
		res = 0
		for i in dominoes:
			i = sorted(i)
			if str(i) not in d:
				d[str(i)] = 0
			d[str(i)] += 1
			if d[str(i)] > 1:
				res += d[str(i)] - 1
		print(d)
		return res


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		return sum((d * (d - 1) // 2 for d in Counter((tuple(sorted(domino)) for domino in dominoes)).values()))


from collections import defaultdict

class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		d = {}
		for domi in dominoes:
			p = tuple(sorted(domi))
			if p in d:
				d[p] += 1
			else:
				d[p] = 1
		c = 0
		for n in list(d.values()):
			s = n * (n - 1) // 2
			c += s
		return c


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		s = []
		for i in range(len(dominoes)):
			dominoes[i] = sorted(dominoes[i])
			if dominoes[i] not in s:
				s.append(dominoes[i])
		re = 0

		def fac(n):
			if n == 0:
				return 1
			if n < 3:
				return n
			return n * fac(n - 1)
		for r in s:
			c = dominoes.count(r)
			re += int(fac(c) / (fac(c - 2) * 2))
		print(dominoes, s, re)
		return re


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		dominoes_dict = {}
		for i in [frozenset(domino) for domino in dominoes]:
			if i not in dominoes_dict:
				dominoes_dict[i] = 1
			else:
				dominoes_dict[i] += 1
		return sum([int(n * (n - 1) / 2) for n in list(dominoes_dict.values()) if n > 1])


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		dicts = defaultdict(int)
		ans = 0
		for domi in dominoes:
			dicts[tuple(sorted(domi))] += 1
		for n in dicts.values():
			ans += n * (n - 1) // 2
		return ans


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		collection = defaultdict(int)
		count = 0
		for i in dominoes:
			pair = frozenset(i)
			count += collection[pair]
			collection[pair] += 1
		return count


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		from collections import defaultdict
		counter = defaultdict(int)
		for domino in dominoes:
			counter[tuple(sorted(domino))] += 1
		return sum([v * (v - 1) // 2 for v in counter.values()])


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		d = {}
		for dom in dominoes:
			p = tuple(sorted(dom))
			if p in d:
				d[p] += 1
			else:
				d[p] = 1
		c = 0
		for n in d.values():
			s = n * (n - 1) // 2
			c += s
		return c


from math import comb

class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		hashtable = {}
		for d in dominoes:
			new = tuple(sorted(d))
			if new not in list(hashtable.keys()):
				hashtable[new] = 1
			else:
				hashtable[new] += 1
		counter = 0
		print(hashtable)
		for (k, v) in list(hashtable.items()):
			if v >= 2:
				counter += comb(v, 2)
		return counter


class Solution:

	def numEquivDominoPairs(self, dominoes: List[List[int]]) -> int:
		count_dict = {}
		total_count = 0
		for d in dominoes:
			d = tuple(sorted(d))
			if d in count_dict:
				total_count += count_dict[tuple(d)]
				count_dict[d] += 1
			else:
				count_dict[d] = 1
		return total_count