In a deck of cards, each card has an integer written on it.
Return true if and only if you can choose X >= 2 such that it is possible to split the entire deck into 1 or more groups of cards, where:

Each group has exactly X cards.
All the cards in each group have the same integer.

 
Example 1:
Input: deck = [1,2,3,4,4,3,2,1]
Output: true
Explanation: Possible partition [1,1],[2,2],[3,3],[4,4].

Example 2:
Input: deck = [1,1,1,2,2,2,3,3]
Output: false´
Explanation: No possible partition.

Example 3:
Input: deck = [1]
Output: false
Explanation: No possible partition.

Example 4:
Input: deck = [1,1]
Output: true
Explanation: Possible partition [1,1].

Example 5:
Input: deck = [1,1,2,2,2,2]
Output: true
Explanation: Possible partition [1,1],[2,2],[2,2].

 
Constraints:

1 <= deck.length <= 10^4
0 <= deck[i] < 10^4

Source: leetcode | Difficulty: EASY
Tags: Number theory

Data structures

Mathematics

Starter code: class Solution:
    def hasGroupsSizeX(self, deck: List[int]) -> bool:
        

Solutions:
class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:

		def findGCD(a, b):
			if b == 0:
				return a
			return findGCD(b, a % b)
		hash_cards = {}
		for card in deck:
			if card in hash_cards:
				hash_cards[card] += 1
			else:
				hash_cards[card] = 1
		value_ = list(hash_cards.values())
		res = value_[0]
		for x in value_[1:]:
			res = findGCD(res, x)
		if res < 2:
			return False
		return True


class Solution:

	def gcd(a, b):
		if b % a == 0:
			return a
		elif a % b == 0:
			return b
		elif b > a:
			return gcd(a, b - a)
		else:
			return gcd(a - b, b)

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		if len(deck) == 0 or len(deck) == 1:
			return False
		d = list(set(deck))
		if len(d) == 1 and len(deck) >= 2:
			return True
		s = gcd(deck.count(d[0]), deck.count(d[1]))
		if s < 2:
			return False
		for i in range(2, len(d)):
			if gcd(s, deck.count(d[i])) < 2:
				return False
			s = gcd(s, deck.count(d[i]))
		return True


def gcd(a, b):
	if b == 0:
		return a
	else:
		return gcd(b, a % b)

class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		arr = {}
		for i in range(len(deck)):
			if deck[i] in arr:
				arr[deck[i]] += 1
			else:
				arr[deck[i]] = 1
		list1 = list(arr.values())
		mi = list1[0]
		for c in list1[1:]:
			mi = gcd(mi, c)
		if mi < 2:
			return False
		for i in list(arr.values()):
			if i % mi != 0:
				return False
		return True


class Solution:

	def gcd(self, a, b):
		if b == 0:
			return a
		else:
			return gcd(b, a % b)

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		hashmap = {}
		for i in range(len(deck)):
			try:
				hashmap[deck[i]] += 1
			except:
				hashmap[deck[i]] = 1
		vals = set(list(hashmap.values()))
		gcd_val = next(iter(vals))
		for i in vals:
			gcd_val = gcd(gcd_val, i)
			if gcd_val == 1:
				return False
		return True


class Solution:

	def fill(self, A, B):
		for i in range(len(A)):
			B[A[i]] += 1
		return list(filter(lambda a: a != 0, B))

	def mcd(self, arr):
		MCD = min(arr)
		for i in range(1, len(arr)):
			MCD = math.gcd(MCD, arr[i])
		return MCD

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		if len(deck) < 2:
			return False
		deck.sort()
		B = [0] * (max(deck) + len(deck))
		B = self.fill(deck, B)
		for i in range(len(B) - 1):
			if B[i] == 1:
				return False
		MCD = self.mcd(B)
		if MCD == 1:
			return False
		return True


class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		hashMap = {}
		boolean = False
		lenght = len(deck)
		if lenght < 2:
			return False

		def commonFactor(a, b):
			if b == 0:
				return a
			else:
				return commonFactor(b, a % b)
		for i in range(lenght):
			if hashMap.get(deck[i]) is not None:
				hashMap[deck[i]] = hashMap[deck[i]] + 1
			else:
				hashMap[deck[i]] = 1
		for i in range(lenght):
			if hashMap[deck[i]] == 1:
				return False
			elif i < lenght - 1 and commonFactor(hashMap[deck[i]], hashMap[deck[i + 1]]) > 1:
				boolean = True
			elif i == lenght - 1 and commonFactor(hashMap[deck[i]], hashMap[deck[i - 1]]) > 1:
				boolean = True
			else:
				return False
		return boolean


class Solution:

	def hasGroupsSizeX(self, deck):
		count = collections.Counter(deck)
		N = len(deck)
		for X in range(2, N + 1):
			if N % X == 0:
				if all((v % X == 0 for v in count.values())):
					return True
		return False


class Solution:

	def commondenominator(self, a, b):
		temp = b
		while temp > 1:
			if a % temp == 0 and b % temp == 0:
				return temp
			temp -= 1
		return -1

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		if not deck or len(deck) < 2:
			return False
		d = dict()
		for x in deck:
			if x not in d:
				d[x] = 1
			else:
				d[x] += 1
		mini = float('inf')
		ret = 1
		for x in d:
			if mini == float('inf'):
				mini = d[x]
				continue
			if d[x] != mini:
				ret = self.commondenominator(d[x], mini)
				if ret < 0:
					return False
				else:
					mini = ret
		return True


from functools import reduce

class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		from fractions import gcd
		vals = list(collections.Counter(deck).values())
		return reduce(gcd, vals) >= 2


class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		N = len(deck)
		if N <= 2:
			if N == 1:
				return False
			if len(set(deck)) == 1:
				return True
			else:
				return False
		cardCount = defaultdict(int)
		for card in deck:
			cardCount[card] += 1
		gcd = list(cardCount.values())[0]
		for val in list(cardCount.values())[1:]:
			gcd = math.gcd(gcd, val)
		return True if gcd >= 2 else False


class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		from collections import Counter
		cards = Counter(deck)
		min_cnt = min(cards.values())
		for i in range(2, min_cnt + 1):
			divided = [v % i for v in list(cards.values())]
			if not any(divided):
				return True
		return False


from collections import Counter

class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		if len(deck) < 2:
			return False
		deck_count = Counter(deck)
		v = set(deck_count.values())
		min_v = min(v)
		v_dict = dict()
		all_factors = set()
		for num in v:
			for j in range(2, min_v + 1):
				if num % j == 0:
					if num in v_dict:
						v_dict[num].add(j)
					else:
						v_dict[num] = set()
						v_dict[num].add(j)
					all_factors.add(j)
		if len(v_dict) != len(v):
			return False
		for i in list(v_dict.values()):
			all_factors = all_factors.intersection(i)
		if len(all_factors) > 0:
			return True
		return False


class Solution:

	def hasGroupsSizeX(self, deck):

		def gcd(a, b):
			while b:
				(a, b) = (b, a % b)
			return a
		count = [*list(Counter(deck).values())]
		g = count[0]
		for i in range(len(count)):
			g = gcd(g, count[i])
			if g == 1:
				return False
		return True


class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		deck1 = list(set(deck))
		len1 = []
		for j in range(len(deck1)):
			leny = len([number for number in deck if number == deck1[j]])
			len1.append(leny)
		count = 2
		while count <= len(deck):
			if len(deck) % count == 0:
				ty = len([number for number in len1 if number % count > 0])
				if ty == 0:
					return True
					break
			count = count + 1
		return False


def gcd(a, b):
	if b == 0:
		return a
	else:
		return gcd(b, a % b)

class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		count = list(collections.Counter(deck).values())
		list1 = list(count)
		mi = list1[0]
		for c in list1[1:]:
			mi = gcd(mi, c)
		if mi < 2:
			return False
		for i in count:
			if i % mi != 0:
				return False
		return True


class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		counter = collections.Counter(deck)
		for i in counter:
			if counter[i] < 2:
				return False
		cur_gcd = 0
		for i in counter:
			cur_gcd = gcd(cur_gcd, counter[i])
		if cur_gcd == 1:
			return False
		return True


class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		count = collections.Counter(deck)
		val = list(count.values())
		gcd = val[0]
		for i in val[1:]:
			gcd = math.gcd(i, gcd)
		return gcd >= 2


class Solution:

	def hasGroupsSizeX(self, deck):
		count = Counter(deck)
		N = len(deck)
		g = lambda X: all((v % X == 0 for v in count.values()))
		f = lambda X: not N % X and g(X)
		return any(map(f, range(2, N + 1)))
		return False


class Solution:

	def fun(m, k, c):
		for i in k:
			if len(i) == m:
				g = len(i) // m
				c += g
			elif len(i) % m == 0:
				c += len(i) // m
		return c

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		deck.sort()
		l = []
		k = []
		l.append(deck[0])
		for i in range(1, len(deck)):
			if l[-1] != deck[i]:
				k.append(l)
				l = []
			l.append(deck[i])
		k.append(l)
		k.sort()
		j = len(k[0])
		if len(k[-1]) == 1:
			return bool(0)
		for i in range(2, len(deck) + 1):
			c = 0
			c += Solution.fun(i, k, c)
			if len(deck) / i == c:
				return bool(1)
		return bool(0)


def compute_gcd(a, b):
	if b == 0:
		return a
	else:
		return compute_gcd(b, a % b)

class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		max_size = int(10000.0 + 1)
		n = len(deck)
		freq = [0 for _ in range(max_size)]
		for i in range(n):
			freq[deck[i]] += 1
		gcd = freq[deck[0]]
		for i in range(max_size):
			gcd = compute_gcd(gcd, freq[i])
		if gcd == 1:
			return False
		return True


class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		d = collections.Counter(deck)
		parts = {}
		for key in d:
			m = d[key]
			if m == 1:
				return False
			parts[m] = parts.get(m, 0) + 1
			i = 2
			while m / i >= 2:
				if m % i == 0:
					parts[m // i] = parts.get(m // i, 0) + 1
				i += 1
		for key in parts:
			if parts[key] == len(d):
				return True
		return False


class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		from collections import Counter
		from math import gcd
		c = Counter(deck)
		cur_g = 0
		for i in c.values():
			cur_g = gcd(cur_g, i)
		return cur_g > 1


class Solution:

	def checkMultiple(self, num, maxLCM):
		d = 2
		while d <= maxLCM:
			if num % d == 0:
				return True
			d += 1
		return False

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		intCnt = {}
		for num in deck:
			if num not in intCnt:
				intCnt[num] = 0
			intCnt[num] += 1
		i = 1
		n = len(intCnt)
		cnts = list(intCnt.values())
		cnts.sort()
		leastDiff = None
		leastCnt = cnts[0]
		while i < n:
			curDiff = cnts[i] - cnts[i - 1]
			if leastDiff == None or curDiff < leastDiff:
				leastDiff = curDiff
			if cnts[i] < leastCnt:
				leastCnt = cnts[i]
			i += 1
		if leastDiff == 0 or leastDiff == None:
			leastDiff = leastCnt
		for num in intCnt:
			if intCnt[num] < 2 or leastDiff <= 1 or (not self.checkMultiple(intCnt[num], leastDiff)):
				return False
		return True


class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		num = dict()
		for i in range(len(deck)):
			if not deck[i] in list(num.keys()):
				num[deck[i]] = 1
			else:
				num[deck[i]] += 1
		minv = 10005
		for (key, value) in list(num.items()):
			if value < minv:
				minv = value
		if minv < 2:
			return False
		possible_share = []
		for i in range(2, minv + 1):
			if minv % i == 0:
				possible_share.append(i)
		for i in possible_share:
			Flag = True
			for (key, value) in list(num.items()):
				if value % i != 0:
					Flag = False
					break
			if Flag:
				return True
		return False


class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		seen = {}
		for card in deck:
			if card in seen:
				seen[card] += 1
			else:
				seen[card] = 1
		for i in range(2, len(deck) + 1):
			if self.helper(seen, i):
				return True
		return False

	def helper(self, seen, val):
		for (key, item) in list(seen.items()):
			if item % val != 0:
				return False
		return True


class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		if len(deck) <= 1:
			return False
		dict1 = {}
		for ele in deck:
			if ele in dict1:
				dict1[ele] += 1
			else:
				dict1[ele] = 1
		for i in range(2, len(deck) + 1):
			if all((v % i == 0 for v in list(dict1.values()))):
				return True
		return False


import collections

class Solution:

	def hasGroupsSizeX(self, deck: List[int]) -> bool:
		if len(deck) <= 1:
			return False
		dict1 = collections.Counter(deck)
		for i in range(2, len(deck) + 1):
			if all((v % i == 0 for v in list(dict1.values()))):
				return True
		return False