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

Difficulty: introductory

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 
      else:  
        if(a%b==0):
            return b
        else:
          if 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):
            #print(\"temp:\", temp, \"a:\", a, \"b:\", b)
            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
        #print(\"d:\", d)
        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)
                #print(\"ret:\", ret)
                if ret < 0:
                    return False
                else:
                    mini = ret   
        #print(\"mini:\", mini)            
        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
            
        
        


class Solution:
    def hasGroupsSizeX(self, deck: List[int]) -> bool:
        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 list(count.values())):
                    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())]
       # print(count)
        g = count[0]
        for i in range(len(count)):
            g = gcd(g, count[i])
            if g == 1:
                return False
        return True
        
        
      #  return reduce(gcd, count) > 1


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:
        # arr = {}
        # for i in range(len(deck)):
        #     if deck[i] in arr:
        #         arr[deck[i]] += 1
        #     else:
        #         arr[deck[i]] = 1
        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);
        # check if X>=2
        
        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)
        
        #print(gcd)
        return gcd>=2

class Solution:
    def hasGroupsSizeX(self, deck):
        count = 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
        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(1e4 + 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 num in deck: d[num] = d.get(num,0)+1
        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): ## !!! max i is minv
            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