Most football fans love it for the goals and excitement. Well, this Kata doesn't.
You are to handle the referee's little notebook and count the players who were sent off for fouls and misbehavior.

The rules:
Two teams, named "A" and "B" have 11 players each; players on each team are numbered from 1 to 11.
Any player may be sent off the field by being given a red card.
A player can also receive a yellow warning card, which is fine, but if he receives another yellow card, he is sent off immediately (no need for a red card in that case). 
If one of the teams has less than 7 players remaining, the game is stopped immediately by the referee, and the team with less than 7 players loses. 

A `card` is a string with the team's letter ('A' or 'B'), player's number, and card's color ('Y' or 'R') - all concatenated and capitalized.
e.g the card `'B7Y'` means player #7 from team B received a yellow card.

The task: Given a list of cards (could be empty), return the number of remaining players on each team at the end of the game (as a tuple of 2 integers, team "A" first).
If the game was terminated by the referee for insufficient number of players, you are to stop the game immediately, and ignore any further possible cards.

Note for the random tests: If a player that has already been sent off receives another card - ignore it.

Difficulty: introductory

Starter code:

def men_still_standing(cards):
	

Solutions:
def men_still_standing(cards):
    # generate teams
    A = {k: 0 for k in range(1, 12)}
    B = A.copy()
    
    for card in cards:
        # parse card
        team = A if card[0] == "A" else B
        player = int(card[1:-1])
        color = card[-1]
        
        if player not in team:
            continue
        
        # record penalty
        team[player] += 1 if color == "Y" else 2
        
        if team[player] >= 2:
            del team[player]
        
        if len(team) < 7:
            break
    
    return len(A), len(B)


class Player:
    def __init__ (self):
        self.red_cards = 0
        self.yellow_cards = 0
    @property
    def excluded (self):
        return (self.red_cards or 
                self.yellow_cards > 1)
    def receive_red (self):
        self.red_cards += 1
    def receive_yellow (self):
        self.yellow_cards += 1

class Team:
    def __init__ (self, size):
        self.size = size
        self.players = {number: Player()
            for number in range(1, size+1)}
    @property
    def count (self):
        return sum(not player.excluded for 
            player in list(self.players.values()))
    def give_red (self, number):
        self.players[number].receive_red()
    def give_yellow (self, number):
        self.players[number].receive_yellow()

def men_still_standing (cards):
    teams = { 'A': Team(11), 'B': Team(11) }
    actions = {
        'R': Team.give_red, 'Y': Team.give_yellow }
    
    import re
    pattern = '(A|B)([0-9]+)(R|Y)'
    for card in cards:
        match = re.match(pattern, card)
        team, player, color = match.group(1, 2, 3)
        actions[color](teams[team], int(player))
        if any(team.count < 7 
               for team in list(teams.values())):
            break
    
    return tuple(team.count for team in list(teams.values()))
        
    
    
    


def men_still_standing(cards):
    teams = {'A': dict.fromkeys(range(1, 12), 2), 'B': dict.fromkeys(range(1, 12), 2)}
    for card in cards:
        t, number, color = card[:1], int(card[1:-1]), card[-1:]
        team = teams[t]
        if number not in team:
            continue
        team[number] -= 2 if color == 'R' else 1
        if team[number] <= 0:
            del team[number]
            if len(team) < 7:
                break
    return len(teams['A']), len(teams['B'])

def men_still_standing(cards):
    players, Y, R = {"A": 11, "B": 11}, set(), set()
    for c in cards:
        if c[:-1] not in R:
            players[c[0]] -= c[-1] == "R" or c[:-1] in Y
        if 6 in players.values():
            break
        (R if (c[-1] == "R" or c[:-1] in Y) else Y).add(c[:-1])
    return players["A"], players["B"]

'''
1.创建A,B两队的字典 key=player几号球员  value=被罚数 初始值都是0 黄牌+1 红牌+2
2.循环cards 先判断是A.B哪队？再判断是几号球员？ 再看是哪个颜色？
3.如果这个队员已经不再team中（淘汰） 则继续循环
4.若为黄色则通过key=player找到value+1 红色则+2
5.若value=2则del
6.如果删除后len(team)<7  跳出循环
7.最后返回len(A) len(B)---因为team=A 浅拷贝
注意：copy是深拷贝 B不会随着A改变而改变
'''
def men_still_standing(cards):
    #起始球员状态
    A={k:0 for k in range(1,12)}
    B=A.copy()
    
    #记录球员信息
    for card in cards:
        team=A if card[0]=='A' else B
        player=int(card[1:-1])
        color=card[-1]
        
        if player not in team: #球员已经被淘汰
            continue
            
        team[player]+=1 if color=='Y' else 2
        
        if team[player]>=2:
            del team[player]
            
        if len(team)<7:
            break
    return len(A),len(B)


def men_still_standing(cards):
    print(cards)
    playersA = {}
    playersB = {}
    
    countA = 11
    countB = 11
        
    for i in range(1, 12):
        playersA[i] = 2
        playersB[i] = 2
        
    for foul in cards:
        team = foul[0]
        
        countA = 11
        countB = 11
        
        if len(foul) == 4:
            number = int(foul[1:3])
            cardColor = foul[3]
            
        else: # 3 letters
            number = int(foul[1])
            cardColor = foul[2]
        
        if cardColor == 'R':
            cardValue = 2
        else:
            cardValue = 1
        
        if team == 'A':
              playersA[number] -= cardValue
        else:
              playersB[number] -= cardValue
        
        for value in list(playersA.values()):
            if value <= 0:
                countA -= 1
              
        for value in list(playersB.values()):
            if value <= 0:
                countB -= 1
                
        if countA < 7 or countB < 7:
            return (countA, countB)
            
    return (countA, countB)


def men_still_standing(cards):
    a = {'n': 11}
    b = {'n': 11}
    for x in cards:
        jg(a if x[0] == 'A' else b, x)
        if a['n'] < 7 or b['n'] < 7: break
    return a['n'], b['n']
def jg(t, x):
    o = t.get(x[1:-1])
    if o == 1:
        t[x[1:-1]] = -1
        t['n'] -= 1
    elif o == None:
        if x[-1] == 'R':
            t[x[1:-1]] = -1
            t['n'] -= 1
        if x[-1] == 'Y':
            t[x[1:-1]] = 1

def men_still_standing(cards):
    sent_off_A = set()
    sent_off_B = set()
    for i, card in enumerate(cards):
        if card.endswith("R"):
            sent_off_B.add(card[1:-1]) if card[0] == "B" else sent_off_A.add(card[1:-1])
        elif card.endswith("Y") and cards[:i].count(card) > 0:
            sent_off_B.add(card[1:-1]) if card[0] == "B" else sent_off_A.add(card[1:-1])
        if len(sent_off_A) == 5 or len(sent_off_B) == 5:
            break
    return (11 - len(sent_off_A), 11 - len(sent_off_B))


def men_still_standing(cards):
    res={'A':[11]+[0]*11, 'B':[11]+[0]*11}
    for c in cards:
        team,num,card=c[0],int(c[1:-1]),c[-1]
        if res[team][num]<2:
            res[team][num]+= 1 if card=="Y" else 2
            if res[team][num]>1: 
                res[team][0]-=1
            if res[team][0]<7:break
    return res['A'][0], res['B'][0]

def men_still_standing(cards):
    players = [[2] * 11, [2] *11]
    AB = {"A":0, "B":1}
    penalty = {"Y": 1, "R": 2}
    for card in cards:
        team, number, color = card[0], int(card[1:-1]), card[-1]
        players[AB[team]][number-1] -= penalty[color]
        if sum(i>0 for i in players[AB[team]]) < 7:
            break
    return tuple((sum(i>0 for i in x) for x in players))


def men_still_standing(cards):
    players = [11,11]
    dic = {}
    for string in cards:
        player = string[:-1]
        if player in dic:
            if dic[player][1] != 'out':
                dic[player][0] = 1
        else:
            if string[len(string) - 1] == 'Y':
                dic[player] = [0,'in']
            else:
                dic[player] = [1,'in']
        if dic[player][0] == 1 and dic[player][1] is 'in':
            if player[0] == 'A':
                players[0] -= 1
            else:
                players[1] -= 1
            dic[player][1] = 'out'
        if players[0] < 7 or players[1] < 7:
            return tuple(players)
    return tuple(players)


def men_still_standing(cards):
    teams = {
        'A': [ True, True, True, True, True, True, True, True, True, True, True ],
        'B': [ True, True, True, True, True, True, True, True, True, True, True ],       
    }
    for card in cards:
        team = card[0]
        color = card[-1]
        player = int(card[1:-1]) - 1
        if color == 'R' or teams[team][player] == 'Y':
            teams[team][player] = False
        elif color == 'Y' and teams[team][player] != False:
            teams[team][player] = 'Y'
        if len([1 for (_, team) in list(teams.items()) if players_up(team) >= 7]) < 2:
            break
    return (players_up(teams['A']), players_up(teams['B']))
  
def players_up(players):
    return len([1 for player in players if player != False])


find=lambda d1,d2:(sum(1for j in d1.values()if len(j)<2and"R"not in j),sum(1for j in d2.values()if len(j)<2and"R"not in j))
def men_still_standing(a):
    d1 = {i: [] for i in range(1, 12)}
    d2 = __import__("copy").deepcopy(d1)
    for i in a:
        [d1,d2][i[0] == "B"][int(i[1:-1])].append(i[-1])
        r = find(d1,d2)
        if any(j < 7 for j in r) : return r
    return find(d1,d2)

from collections import defaultdict
def men_still_standing(cards):
    book = [defaultdict(int), defaultdict(int)]
    f = lambda book: sum((-1 for b in book.values() if b > 1), 11)
    cnt = [11, 11]
    for c in cards:
        team, num, card = c[0] == 'B', c[1:-1], c[-1]
        book[team][num] += (1,2)[card == 'R']
        cnt = list(map(f, book))
        if min(cnt) < 7:
            break
    return tuple(cnt)

def men_still_standing(cards):
    A = {str(i):0 for i in range(1,12)}
    B = A.copy()
    for card in cards:
        if (11-sum(1 for i in A.values() if i >= 2)) <= 6 or (11-sum(1 for i in B.values() if i >= 2)) <= 6: break
        if card[-1] == 'Y': eval(card[0])[card[1:-1]] += 1 
        elif card[-1]=="R": eval(card[0])[card[1:-1]] += 2
    return (max(11-sum(1 for i in A.values() if i >= 2), 6), max(11-sum(1 for i in B.values() if i >= 2),6))

def men_still_standing(cards):
    red = []
    yellow = []
    still_playing = {"A": 11, "B": 11}

    for card in cards:
        if still_playing["A"] < 7 or still_playing["B"] < 7:
            break

        if card[-1::] == "Y" and card[:-1:] not in red:
            if card[:-1:] not in yellow:
                yellow.append(card[:-1:])
            elif card[:-1:] in yellow:
                red.append(card[:-1:])
                still_playing[card[:1:]] -= 1
        elif card[-1::] == "R" and card[:-1:] not in red:
            red.append(card[:-1:])
            still_playing[card[:1:]] -= 1

    return still_playing["A"], still_playing["B"]

def men_still_standing(cards):
    team_a = {i+1:0 for i in range(11)}
    team_b = team_a.copy()
    teams_dict = {'A': team_a, 'B': team_b}    
    gone_players = {'A': [], 'B': []}
    for booking in cards:
        team = teams_dict[booking[0]]
        player = int(booking[1:-1])
        if player in gone_players[booking[0]]:
            continue
        if booking[-1]=='R':
            team[player] +=1
        else:
            team[player] +=0.5
        if team[player] >= 1:
            gone_players[booking[0]].append(player)
        if len(gone_players[booking[0]]) > 4:
            break
    return tuple([11 - len(gone_players['A']), 11 - len(gone_players['B'])])
        


def men_still_standing(cards):
    A_sentoff = set()
    B_sentoff = set()
    
    for index, card in enumerate(cards):
        if card[-1] == "R":
            A_sentoff.add(card[1:-1]) if card[0] == "A" else B_sentoff.add(card[1:-1])
        elif card[-1] == "Y" and cards[:index].count(card) > 0:
            A_sentoff.add(card[1:-1]) if card[0] == "A" else B_sentoff.add(card[1:-1])
        
        if len(A_sentoff) == 5 or len(B_sentoff) == 5:
            break
    
    a_remaining = 11 - len(A_sentoff)
    b_remaining = 11 - len(B_sentoff)
    
    return (a_remaining, b_remaining)

def men_still_standing(cards):
    if cards == []: return (11, 11)
    a, b = [1]*11, [1]*11
    dicA, dicB = {}, {}
    for i in cards:
        if i[-1] == 'Y':
            if i[:-1] in dicA:
                a[dicA[i[:-1]]-1] = 0
            elif i[:-1] in dicB:
                b[dicB[i[:-1]]-1] = 0
            else:
                if i[0] == 'A':
                    dicA[i[:-1]] = int(i[1:-1])
                else:
                    dicB[i[:-1]] = int(i[1:-1])
        elif i[-1] == 'R':
            if i[0] == 'A':
                a[int(i[1:-1])-1] = 0
            elif i[0] == 'B':
                b[int(i[1:-1])-1] = 0
        if sum(a) == 6 or sum(b) == 6:
            return (sum(a), sum(b))
    return (sum(a),sum(b))


def men_still_standing(cards):

    print(cards)
    
    Team_A = 11
    Team_B = 11
    
    Yellows = []
    Reds = []
    
    for event in cards:
        
        if Team_A == 6 or Team_B == 6: #Traps too few players and abandons the match
            #print ("Match abandoned")
            return (Team_A, Team_B)

        else:
        
            print(event)

            if event[-1] == "R" and event[0:(len(event)-1)] not in Reds:
    
                print("Red card event")
    
                Reds.append(event[0:(len(event)-1)]) # Add player to list of sent off players
                print("Red Cards",Reds) 
    
                if event[0] == "A":
                    Team_A -= 1
                    print("Team A remaining = ",str(Team_A))
                else:
                    Team_B -= 1
                    print("Team B remaining = ",str(Team_B))
    
            elif event[-1] == "Y" and event[0:(len(event)-1)] in Yellows and event[0:(len(event)-1)] not in Reds:
                print("2nd Yellow Card event, Player sent off", Reds)
                Reds.append(event[0:(len(event)-1)]) # Add player to list of sent off players
    
                if event[0] == "A":
                    Team_A -= 1
                    print("Team A remaining = ",str(Team_A))
                else:
                    Team_B -= 1
                    print("Team B remaining = ",str(Team_B))   
    
            elif event[-1] == "Y":
                    
                    if event[0:(len(event)-1)] in Reds:
                        print("Player already sent off")
                    else:
                        Yellows.append(event[0:(len(event)-1)]) # Add player to list of players with a Yellow card
                        print("Yellow card issued to",Yellows)
            else:
                print("player already sent off!")
    
    print(Team_A, Team_B)
    
    return(Team_A, Team_B)