Departamento de Ciência da
Computação - IME - USP
Nesta questão considere expressões na forma posfixa como no EP4, porém formada apenas por números inteiros e pelos operadores '+', '-', '*', '/', '%', '^' e '!' (os mesmos operadores do EP4, a menos do operador de atribuição pois não temos variáveis nesta questão).
Uma expressão é bem formada se há operandos para todos os operadores e vice-versa.
Item (a)Escreva a seguinte função:
def verifica(exp): ''' (str) -> bool Recebe um string exp contendo uma expressão na forma posfixa. Retorna True caso exp esteja bem formada e, em caso contrário, retorna False. '''
Exemplos de execuções da função verifica():
>>> verifica( '+' ) False >>> verifica( '12' ) True >>> verifica( '2 3' ) False >>> verifica( '1+3' ) False >>> verifica( '365 18*150+' ) True >>> verifica( '21 6 +345*789-!!' ) True \end{verbatim}
DIGITOS = '0123456789' BINARIOS = '+-*/%^' UNARIOS = '!' def verifica(exp): ''' (str) -> bool Recebe um string exp contendo uma expressão na forma posfixa. Retorna True caso exp esteja bem formada e, em caso contrário, retorna False. ''' # acrecente um espaço no final da expressão para analisar # o último token ainda dentro do laço for. exp += ' ' numero_str = '' # para armazenar um número topo = 0 # simula o número de operandos na pilha de execução for car in exp: if car in DIGITOS: numero_str += car else: # estávamos contruindo um número? if numero_str != '': # simule empilhamento do número na pilha de execução topo += 1 numero_str = '' if car in BINARIOS: # simule desempilhamento de 2 operandos e empilhamento do resultado if topo < 2: return False topo -= 1 elif car in UNARIOS: # simule desempilhamento de 1 operando e empilhamento do resultado if topo < 1: return False # mais de um operando na pilha de excução if topo != 1: return False return True
def verifica(exp): ''' (str) -> bool Recebe um string exp contendo uma expressão na forma posfixa. Retorna True caso exp esteja bem formada e, em caso contrário, retorna False. ''' n = len(exp) topo = 0 # simula o número de operandos na pilha de execução i = 0 while i < n: if exp[i] in DIGITOS: # simule empilhamento do número topo += 1 # pule o número while i < n and exp[i] in DIGITOS: i += 1 # vá para o próximo caractere # volte, pois no final do while i é sempre incrementado i -= 1 elif exp[i] in BINARIOS: # simule desempilhamento de 2 operandos e empilhamento do resultado if topo < 2: return False topo -= 1 elif exp[i] in UNARIOS: # simule desempilhamento de 1 operando e empilhamento do resultado if topo < 1: return False i += 1 # vá para o próximo caractere # mais de um operando na pilha de excução? if topo != 1: return False return TrueItem (a)
Escreva um programa (função main()) que permite ao usuário testar várias expressões posfixas como definidas no item anterior, utilizando, obrigatoriamente, a função verifica(). Você pode utilizar a função mesmo que não a tenha escrito. A cada expressão digitada pelo usuário, o programa deve imprimir se ela é válida ou inválida. O programa deve terminar quando o usuário digitar a palavra fim.
Exemplo de execução do programa:
exp>> ! Inválida exp>> 1 2 + Válida exp>> 00112+765 Inválida exp>> 210 345678 Inválida exp>> 00112 4 56 7890+-!*!!! Válida exp>> fim Obrigado por usar o programa
PROMPT = 'exp>> ' FIM = 'fim' def main(): exp = input(PROMPT) while exp != FIM: if verifica(exp): print("Válida\n") else: print("Inválida\n") exp = input(PROMPT)
Considere a seguinte versão simplificada de um jogo de bingo que chamaremos de BIN.
Em um jogo de BIN cada jogador possui uma cartela. Alguns exemplos de cartelas de BIN são mostrados abaixo:
Cartela 1: Cartela 2: Cartela 3: B 3 7 1 B 3 6 2 B 5 0 1 I 3 8 0 I 4 5 8 I 5 0 1 N 9 7 5 N 2 6 1 N 7 0 5
Cada linha da cartela, identificadas pelas letras 'B', 'I', e 'N', possui 3 números entre 0 e 9, sem repetição. Note, entretanto, que um número pode se repetir em linhas distintas da cartela.
Em um jogo de BIN, um mestre de cerimônias anuncia uma combinação após a outra sem repetições, como, por exemplo, 'B2', 'I7', |'N4'|, ... Portanto, cada combinação é composta por uma letra que identifica a linha ('B', |'I'|, ou 'N') e um número (entre 0 e 9).
Cada jogador deve marcar na sua cartela as combinações anunciadas que estejam presentes na cartela. Uma cartela é vencedora se todas as suas 9 combinações estiverem marcadas.
Nesta questão você deverá escrever um programa (função main()) que simula um jogo de BIN. Cada cartela deverá ser representada no programa por dicionário nativos do Python. No dicionário as chaves deverão ser as combinações presentes na cartela e o \textbf{valor} associado deverá indicar se a combinação está ou não marcada.
Item (a)Escreva uma classe Cartela que:
ao ser criado, um objeto dessa classe representará uma cartela com as suas 9 combinações.
Para gerar as combinações ('B', 'I', e 'N' junto com um número entre 0 e 9) deverá ser usada uma função sorteia() que retorna um número aleatório entre 0 e 9. Não escreva a função sorteia() apenas use-a.
Utilize um dicionário para armazenar as combinações da cartela.
possui um método marca(), que recebe um string representando uma combinação (como 'I7') e marca a combinação caso ela esteja na cartela.
O método deve retornar True se todas as combinações da cartela estiverem marcadas, e False em caso contrário.
B 3 7 1 I 3 8 0 N 9 7 5
class Cartela: def __init__(self): '''(Cartela) -> None Função mágica que recebe a referência a um objeto e cria um objeto da classe Cartela e o "retorna" (via referência). ''' self.jogo = {} while len(self.jogo) < 3: self.jogo['B%d'%(sorteia())] = 0 while len(self.jogo) < 6: self.jogo['I%d'%(sorteia())] = 0 while len(self.jogo) < 9: self.jogo['N%d'%(sorteia())] = 0 def __str__(self): '''(Cartela) -> str Recebe uma cartela self e produz ume retorna o string que será utilizado pela função print() para imprimir o objeto. ''' b = 'B ' i = 'I ' n = 'N ' for chave in self.jogo: if chave[0] == 'B': b += chave[1] + ' ' elif chave[0] == 'I': i += chave[1] + ' ' else: n += chave[1] + ' ' return b + '\n' + i + '\n' + n + '\n' def marca(self, lance): ''' (Cartela, str) -> bool Recebe uma cartela self, um string lance representando e uma combinação e marca essa combinação caso esteja presente na cartela. ''' if lance in self.jogo: self.jogo[lance] = 1 cont = 0 for chave in self.jogo: cont += self.jogo[chave] return cont == 9 return False
class Cartela: #-------------------------------------- def __init__(self): '''(Cartela) -> None Função mágica que recebe a referência a um objeto e cria um objeto da classe Cartela e o "retorna" (via referência). ''' self.dicio = {} for letra in "BIN": i = 0 while i < 3: chave = letra + str(sorteia()) valor = False if not chave in self.dicio: self.dicio[chave] = valor i += 1 self.sorteados = 0 #-------------------------------------- def __str__(self): '''(Cartela) -> str Recebe uma cartela self e produz ume retorna o string que será utilizado pela função print() para imprimir o objeto. ''' b = "B" i = "I" n = "N" for chave in self.dicio: numero_str = " %s" %(chave[1]) if chave[0] == 'B': b += numero_str elif chave[0] == 'I': i += numero_str else: n += numero_str return b + "\n" + i + "\n" + n + "\n" #-------------------------------------- def marca(self,lance): ''' (Cartela, str) -> bool Recebe uma cartela self, um string lance representando e uma combinação e marca essa combinação caso esteja presente na cartela. ''' valor = self.dicio.get(lance) if valor != None: self.dicio[lance] = True self.sorteados += 1 if self.sortedados == 9: return True return FalseItem (b)
Neste item utilize a classe Cartela do item anterior, mesmo que você não a tenha escrito. Você deverá escrever um programa em Python (a função main) que simule um jogo de BIN com apenas 2 jogadores.
Cada jogador deve possuir uma cartela. O programa deve ler as combinações do teclado (na forma de strings como 'B4', 'I7', 'N3' etc) até que a cartela de um dos (ou ambos) jogadores tenha todas as suas combinações marcadas. Quando uma cartela tiver todas as suas combinações marcadas, o programa deve imprimir ``BIN!!''.
Além disso, quando o jogo terminar, o programa deve imprimir a sequência completa de combinações, e imprimir a(s) cartela(s) vencedora(s) e a cartela perdedora (se houver).
Por exemplo, considere as seguintes cartelas
Cartela 1: Cartela 2: Cartela 3: B 0 1 4 B 8 0 5 B 8 1 3 I 4 6 1 I 2 8 5 I 1 6 4 N 8 0 6 N 2 3 5 N 3 8 2e a seguinte sequência de lances: 'B4', 'B0', 'I6', 'I1', 'N6', 'N0', 'N2', 'B8', 'B3', 'N3', 'N8', 'B1', 'I4'.
A primeiro exemplo mostra como o seu programa deve se comportar quando os jogadores possuem as cartelas 1 e 2, respectivamente, e a segundo exemplo mostra como o seu programa deve se comportar quando os jogadores possuem as cartela 1 e 3, para a mesma entrada.
BEM VINDO AO BIN!! Digite um lance: B4 Digite um lance: B0 Digite um lance: I6 Digite um lance: I1 Digite um lance: N6 Digite um lance: N0 Digite um lance: N2 Digite um lance: B8 Digite um lance: B3 Digite um lance: N3 Digite um lance: N8 Digite um lance: B1 Digite um lance: I4 BIN!! lances: B4 B0 I6 I1 N6 N0 N2 B8 B3 N3 N8 B1 I4 cartela vencedora: B 1 4 0 I 4 1 6 N 6 8 0 cartela perdedora: B 8 5 0 I 5 2 8 N 3 5 2 ----------------------------------------------- BEM VINDO AO BIN!! Digite um lance: B4 Digite um lance: B0 Digite um lance: I6 Digite um lance: I1 Digite um lance: N6 Digite um lance: N0 Digite um lance: N2 Digite um lance: B8 Digite um lance: B3 Digite um lance: N3 Digite um lance: N8 Digite um lance: B1 Digite um lance: I4 BIN!! BIN!! lances: B4 B0 I6 I1 N6 N0 N2 B8 B3 N3 N8 B1 I4 cartela vencedora: B 0 1 4 I 1 6 4 N 6 8 0 cartela vencedora: B 8 3 1 I 4 6 1 N 8 3 2
def main(): print("BEM VINDO AO BIN!!") # crie duas cartelas, uma para cada jogador cartela_1 = Cartela() cartela_2 = Cartela() # inicializações antes do jogo venceu_1, venceu_2 = False, False registro_lances = '' while not venceu_1 and not venceu_2: # mestre de cerimônia anuncia lance lance = input("Digite um lance: ") # registre o lance registro_lances += lance + " " # verifique se o jogador 1 venceu venceu_1 = cartela_1.marca(lance) if venceu_1: print("\nBIN!!") #verifique se o jogador 2 venceu venceu_2 = cartela_2.marca(lance) if venceu_2: print("\nBIN!!") # exiba os lances print("lances: %s\n"%registro_lances) if venceu_1 and venceu_2: print("cartela vencedora:") print(cartela_1) print("cartela vencedora:") print(cartela_2) elif venceu_1: print("cartela vencedora:") print(cartela_1) print("cartela perdedora:") print(cartela_2) else: print("cartela vencedora:") print(cartela_2) print("cartela perdedora:") print(cartela_1)