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 True
Item (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 False
Item (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 2
e 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)