Departamento de Ciência da Computação - IME - USP

MAC2166 Introdução à Computação

Escola Politécnica - Primeiro Semestre de 2015

Prova Substitutiva


QUESTÃO 1

Esta questão consiste na implementação de duas funções em Python. Uma das funções é o main() e a outra é uma função de nome lecker().

Dizemos que uma lista de números inteiros é lecker se ela tem apenas 1 elemento que é maior que seus vizinhos. Por exemplo,

Item (a)

Escreva uma função lecker() que recebe uma lista de números e retorna True se a lista é lecker e False em caso contrário.

SOLUÇÃO

def lecker(lista):
    '''(list) -> bool

    Recebe uma lista e retorna True se ela é lecker.
    Uma lista de número é lecker se tem apenas 1 
    "máximo local".
    '''
    n = len(lista)

    # lista muito pequena tratamos na mão
    if n == 1:
        return False 

    # número de máximos locais
    no_máximos = 0
 
    # verifique o início esquerdo da lista
    if lista[0] > lista[1]:
        no_máximos += 1

    # verifique o meio da lista    
    for i in range(1,n-1):
        if lista[i-1] < lista[i] and lista[i] < lista[i+1]: 
            no_máximos += 1

    # verifique o final da lista        
    if lista[n-1] > lista[n-2]:
        no_máximos += 1
     
    return no_máximos == 1    

Item (b)

Uma matriz é lecker se cada uma das listas formada por linhas da matriz e cada uma das listas formada por colunas da matriz forem lecker. Por exemplo,

 número de  linhas = 3    número de  linhas = 3    número de  linhas = 4    número de  linhas = 4   
 número de colunas = 4    número de colunas = 4    número de colunas = 3    número de colunas = 3
 matriz:                  matriz:                  matriz:                  matriz:
    1   2   3   4            1   2   3   5            1   2   3                1   2   3
    8   7   6   5            8   7   6   4            5   8   7                5   8   7
    9  10  11  12            9  10  11  12            6   4   9                6   9  13
 A matriz é lecker!       A matriz não é lecker!     10  11  12               10  11  12  
                                                   A matriz não é lecker!   A matriz é lecker!

Escreva uma função main() que leia inteiros n_lin e n_col, 0 < n_lin, n_col, e uma matriz de números inteiros com n_lin linhas e n_col colunas e imprime uma mensagem indicando se a matriz é ou não lecker. Utilize obrigatoriamente a função lecker() do item anterior mesmo que você não a tenha feito.

A seguir está um exemplo de execução da função main(). O seu programa pode utilizar sem escrevê-la uma função imprima_matriz() que recebe uma matriz e a imprime como mostrado no exemplo de execução.

Verificador de leckerdesa

Digite o número de linhas  da matriz: 3
Digite o número de colunas da matriz: 4
Digite o elemento [0][0]: 1
Digite o elemento [0][1]: 2
Digite o elemento [0][2]: 3
Digite o elemento [0][3]: 5
Digite o elemento [1][0]: 8
Digite o elemento [1][1]: 7
Digite o elemento [1][2]: 6
Digite o elemento [1][3]: 4
Digite o elemento [2][0]: 9
Digite o elemento [2][1]: 10
Digite o elemento [2][2]: 11
Digite o elemento [2][3]: 12

número de linhas  = 3
número de colunas = 4
  1   2   3   5 
  8   7   6   4 
  9  10  11  12 

A matriz não é lecker!

SOLUÇÃO

def main():
    '''
    Programa que verifica se uma dada matriz de números
    é lecker.
    '''
    print("Verificador de leckerdesa")

    # 1 leia as dimensões da matriz
    n_lin = int(input("Digite o número de linhas  da matriz: "))
    n_col = int(input("Digite o número de colunas da matriz: "))

    # 2 leia os elementos e crie a matriz 
    matriz = []
    for i in range(n_lin):
        linha = []
        for j in range(n_col):
            num = int(input("Digite o elemento [%d][%d]: " %(i,j)))
            linha.append(num)
        matriz.append(linha)    

    # 3 imprima a matriz
    imprima_matriz(matriz)
 
    # 4 a matriz é lecker até que se prove o contrário    
    é_lecker = True

    # 5 verifique se as linhas são lecker
    i = 0
    while i < n_lin and é_lecker:
        é_lecker = lecker(matriz[i])
        i += 1 # vá para a próxima linha

    # 6 verifique se as colunas são lecker
    j = 0
    while j < n_col and é_lecker:
        # copie a coluna para uma lista
        coluna = []
        for i in range(n_lin):
            coluna.append(matriz[i][j])
        é_lecker = lecker(coluna)
        j += 1 # vá para a próxima coluna

    # 7 imprima o veredicto
    if é_lecker:
        print("A matriz e lecker!")
    else:
        print("A matriz não é lecker!")


QUESTÃO 2

Nesta questão você escreverá um programa em Python que simula uma partida de uma versão simplificação de um jogo de cartas chamado War. (Esse jogo foi desenvolvido para muitas plataformas, incluindo Android, Apple IOS e Windows Phones. Como não há decisões no jogo e o resultado é totalmente aleatório, War não é considerado um jogo segundo algumas definições [Wikipedia].)

War é um jogo entre dois jogadores. No início de uma partida de War as cartas de um baralho são embaralhadas. Em seguida, cada um dos dois jogadores recebe metade das 52 cartas do baralho. Cada carta recebida por um jogador é colocada em um monte à sua frente. Cada partida do jogo é composta por 26 rodadas. Em cada rodada, simultaneamente, cada jogador pega a carta que está no topo do seu monte e a mostra ao adversário. O vencedor da rodada é o jogador que tiver a carta de maior valor. Em uma rodada pode haver empate. O vencedor da partida é o jogador que vencer mais rodadas. Em uma partida também pode haver empate. Nesta questão, os jogadores da partida de War simulada pelo seu programa serão dois físicos ilustres do Instituto de Tecnologia da Califórnia (Caltech): Sheldon Cooper (Sheldon) e Leonard Hofstadter (Leonard).

A seguir é exibido o resultado de uma partida de War jogada entre Sheldon e Leonard.

Sheldon: ♠K  ♠Q  ♠J  ♢5  ♡3  ♢8  ♡2  ♠D  ♢A  ♣A  ♢Q  ♢7  ♡K  ♣6  ♢9  ♣Q  ♠6  ♣2  ♡7  ♡D  ♢6  ♡9  ♣J  ♠8  ♢D  ♡J 
Leonard: ♢4  ♣9  ♣D  ♠2  ♠3  ♠4  ♣4  ♢3  ♣7  ♣K  ♡5  ♡A  ♡4  ♣5  ♢K  ♠A  ♢2  ♠9  ♠5  ♢J  ♣3  ♠7  ♡8  ♡Q  ♡6  ♣8 
Venceu :  S   S   S   S   E   S   L   S   S   S   S   L   S   S   L   L   S   L   S   L   S   S   S   L   S   S 

Na partida exemplificada acima, cada coluna corresponde a uma rodada. Na linha com o rótulo Venceu, um caractere 'S' indica que Sheldon venceu a rodada correspondente à coluna, um caractere 'L' indica que Leonard venceu a rodada correspondente a coluna, e um caractere 'E' indica que houve empate.

Como pode ser verificado, a primeira rodada foi vencida por Sheldon pois pegou o ♠K enquanto a carta que Leonard pegou foi o ♢4. Na quinta rodada, tivemos um empate, Sheldon e Leonard pegaram cartas de mesmo valor, o ♡3 e o ♠3. A primeira rodada vencida por Leonard foi a sétima quando pegou o ♣4 enquanto que Sheldon pegou o ♡2. O vencedor da partida foi Sheldon pois ele venceu 18 das 26 rodadas.

As constantes definidas abaixo devem ser obrigatoriamente utilizadas nessa questão, sem precisar redefini-las. O valor de cada carta depende apenas de seu posto: 'A', '2', '3', '4', '5', '6', '7', '8', '9', 'D', 'J', 'Q', e 'K'. O dicionário VALOR tem como chave o posto de cada carta e apresenta o seu valor.

# naipes, postos e valores de cada carta de acordo com o posto
# NAIPES  = ['u2661', 'u2665', 'u2662', 'u2663']
NAIPES  = ['♡', '♣', '♢', '♠']
POSTOS  = ['A', '2', '3', '4', '5', '6', '7', '8', '9', 'D', 'J', 'Q', 'K']
VALOR   = {'A':14, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9,
           'D':10, 'J':11, 'Q':12, 'K':13}

Item (a)

Escreva uma classe Carta que será usada para criar um objeto que representa uma carta de um baralho. Essa classe deve obedecer as especificações listadas a seguir.

SOLUÇÃO

#---------------------------------------------
class Carta:
    #-----------------------------------------
    def __init__(self,naipe,posto):
        self.naipe = naipe
        self.posto = posto

    #-----------------------------------------
    def pegue_naipe(self):
        return self.naipe

    #-----------------------------------------
    def pegue_posto(self):
        return self.posto

    #-----------------------------------------
    def pegue_valor(self):
        return VALOR[self.posto]

Item (b)

Escreva uma classe Baralho que será usada para criar um objeto que representa um baralho. Essa classe deve obedecer as especificações listadas a seguir.

SOLUÇÃO

#--------------------------------------------
class Baralho():
    #----------------------------------------
    def __init__(self):
        self.baralho = []
        for naipe in NAIPES:
            for posto in POSTOS:
                carta = Carta(naipe,posto)
                self.baralho.append(carta)

    #----------------------------------------
    def embaralhe(self):
        random.shuffle(self.baralho)

    #----------------------------------------
    def pegue_carta(self):
        carta = self.baralho.pop()
        return carta

Item (c)

Escreva uma classe Jogador que será usada para criar um objeto que representa um jogador de War. Essa classe deve obedecer as especificações listadas a seguir.

SOLUÇÃO

#---------------------------------------------
class Jogador:
    #-----------------------------------------
    def __init__(self, nome):
        self.nome  = nome
        self.monte = []
     
    #-----------------------------------------    
    def __str__(self):
        no_cartas = len(self.monte_jogador)
        s = "%s: " %(self.nome)
        for i in range(no_cartas-1,-1,-1):
            carta = self.monte[i]
            s += carta.pegue_naipe() + carta.pegue_posto() + ' '
        return s
     
    #-----------------------------------------
    def recebe_carta(self,carta):
        self.monte.append(carta)

    #-----------------------------------------
    def pegue_carta(self):
        carta = self.monte.pop()          
        return carta

Item (d)

Neste item você deverá escrever uma função main() que simula uma partida de War entre os jogadores Sheldon e Leonard. A sua função deverá utilizar objetos das classes Carta (item (a)), Baralho (item (b)) e Jogador (item (c)). A seguir estão três exemplos de execução do programa.

War entre Sheldon e Leonard
Sheldon: ♣9  ♢9  ♣4  ♣5  ♢6  ♢Q  ♣K  ♠4  ♡6  ♣6  ♣2  ♠D  ♣J  ♠K  ♠Q  ♡A  ♢8  ♡7  ♢A  ♣D  ♣3  ♢5  ♣7  ♠6  ♢7  ♢J 
Leonard: ♢4  ♢D  ♡3  ♢K  ♠3  ♠2  ♠8  ♠7  ♡D  ♢2  ♡8  ♡9  ♡2  ♡5  ♡J  ♣Q  ♣A  ♣8  ♠J  ♡Q  ♢3  ♠9  ♠A  ♡4  ♠5  ♡K 
Venceu :  S   L   S   L   S   S   S   L   L   S   L   S   S   S   S   S   L   L   S   L   E   L   L   S   S   L 
Sheldon venceu a partida.

War entre Sheldon e Leonard
Sheldon: ♢7  ♡3  ♠9  ♡2  ♠J  ♢8  ♢4  ♣J  ♣4  ♠7  ♣8  ♡A  ♣A  ♢A  ♠5  ♣K  ♢Q  ♢2  ♡Q  ♡9  ♡D  ♠4  ♠3  ♣5  ♠K  ♣Q 
Leonard: ♡7  ♠Q  ♣9  ♣7  ♡K  ♡8  ♣6  ♢9  ♢J  ♡6  ♣2  ♡4  ♠2  ♠A  ♢D  ♠8  ♢6  ♣3  ♢K  ♡J  ♠6  ♠D  ♢5  ♢3  ♡5  ♣D 
Venceu :  E   L   E   L   L   E   L   S   L   S   S   S   S   E   L   S   S   L   L   L   S   L   L   S   S   S 
Sheldon e Leonard empataram a partida.

War entre Sheldon e Leonard
Sheldon: ♡3  ♠2  ♡K  ♢Q  ♡9  ♠3  ♢2  ♣7  ♣A  ♣3  ♠5  ♣D  ♡7  ♢9  ♡8  ♠D  ♠J  ♡6  ♣2  ♢7  ♡A  ♡D  ♠K  ♡2  ♠8  ♣6 
Leonard: ♢8  ♠7  ♠4  ♢3  ♡J  ♡Q  ♣9  ♣J  ♠Q  ♢K  ♢4  ♣5  ♠9  ♢J  ♡4  ♠6  ♣K  ♣4  ♣Q  ♢6  ♡5  ♢A  ♣8  ♢D  ♢5  ♠A 
Venceu :  L   L   S   S   L   L   L   L   S   L   S   S   L   L   S   S   L   S   L   S   S   L   S   L   S   L 
Leonard venceu a partida.

As mensagens emitidas pelo seu programa devem ser idênticas às mensagens mostradas no exemplo. Na simulação de uma partida um baralho deve ser criado e embaralhado. Cada um dos jogadores deve receber metade das 52 cartas do baralho. Cada carta recebida por um jogador é colocada no seu monte. Linhas com os nomes dos jogadores seguidos pelas cartas nos seus montes devem ser impressas, como mostra o exemplo. Em cada uma das rodadas, as cartas no topo dos montes dos jogadores são comparadas. No final da partida devem impressas duas linhas: uma linha contendo o rótulo Venceu: seguido das marcas correspondentes aos vencedor de cada rodada (= SHELDON ou LEONARD) ou ainda a marca representando empate (= EMPATE) e uma linha indicando o jogador que venceu a partida ou se houve empate (veja os exemplos de execução).

A seguir estão alguma constantes que podem ser usadas pela sua função main().

# resultados de uma rodada
SHELDON = 'S'
LEONARD = 'L'
EMPATE  = 'E'

# número de cartas e rodadas
N_CARTAS   = 52
N_RODADAS  = 26

SOLUÇÃO

#------------------------------------------------
def main():
    print("War entre Sheldon e Leonard")

    # 1 crie os jogadores
    sheldon = Jogador("Sheldon")
    leonard = Jogador("Leonard")
       
    # 2 crie baralho
    baralho = Baralho()

    # 3 embaralhe as cartas
    baralho.embaralhe()
    
    # 4 distribua cartas
    for rodadas in range(N_RODADAS):
        carta = baralho.pegue_carta()
        sheldon.recebe_carta(carta)
        carta = baralho.pegue_carta()
        leonard.recebe_carta(carta)

    # 5 mostre cartas dos jogadores
    print(sheldon)
    print(leonard)

    # 6 rodadas
    cont_sheldon = 0 # contador de rodadas vencidas por sheldon
    cont_leonard = 0 # contador de rodadas vencidas por leonard
    vencedores = 'Venceu :'
    for rodada in range(N_RODADAS):
        # pegue cartas dos montes e seu valores
        carta_sheldon = sheldon.pegue_carta()
        valor_sheldon = carta_sheldon.pegue_valor()
        carta_leonard = leonard.pegue_carta()
        valor_leonard = carta_leonard.pegue_valor()

        # verifique quem ganhou a rodada
        if   valor_sheldon == valor_leonard:
            vencedores += '  ' + EMPATE
        elif valor_sheldon  > valor_leonard:
            vencedores += '  ' + SHELDON
            cont_sheldon += 1
        else: # valor_sheldon < valor_leonard
            vencedores += '  ' + LEONARD
            cont_leonard += 1
            
    # 7 mostre lista de vencedores
    print(vencedores)
 
    # 8 mostre vencedor
    if   cont_sheldon == cont_leonard:
        print("Sheldon e Leonard empataram a partida.")
    if   cont_sheldon > cont_leonard:
        print("Sheldon venceu a partida.")
    else: # cont_sheldon < cont_leonard:
        print("Leonard venceu a partida.")


Last modified: Tue Jun 30 20:30:25 BRT 2015