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

MAC2166 Introdução à Computação

Escola Politécnica - Primeiro Semestre de 2014

Prova 1


QUESTÃO 1

      Na figura ao lado, no plano cartesiano, a região sombreada não inclui as linhas de bordo. Note que o eixo y cai bem no meio da figura, e usamos o lado do quadrado para indicar as ordenadas correspondentes.

      Escreva na página do desenho um programa que lê as coordenadas cartesianas (x, y) de um ponto (ambas do tipo float) e imprime entro se esse ponto está na região, e fora caso contrário.

     

    Digite x: 10         Digite x: -3         Digite x: 0
    Digite y: 5          Digite y: 5          Digite y: 3.14149
    fora                 fora                 dentro
    Digite x: -3         Digite x: -3         Digite x: 2
    Digite y: -1         Digite y: 5.5        Digite y: 4.444
    fora                 fora                 fora
    Digite x: -3         Digite x: -3         Digite x: 2.718 
    Digite y: 2          Digite y: 6          Digite y: 5.774
    fora                 fora                 dentro
    Digite x: -3         Digite x: -2         Digite x: 3.14
    Digite y: 2.3        Digite y: 0.5        Digite y: 6.02
    dentro               dentro               fora
    Digite x: -3         Digite x: -1         Digite x: 5
    Digite y: 4          Digite y: 1.5        Digite y: 8
    fora                 fora                 fora 
face

SOLUÇÃO

#--------------------------------------------------------------------
# SOLUÇÃO 1: começa supondo que está dentro e depois...
#     A variável dentro e um indicador de passagem bool.
#
#--------------------------------------------------------------------

x = float(input("Digite x: "))
y = float(input("Digite y: "))

# suponha que (x,y) está dentro
dentro = True

if x <= -5 or 5 <= x or y <= 0 or 8 <= y:
    # aqui sabemos que (x,y) está fora da face
    dentro = False
elif -3 <= x <=  3 and 1 <= y <= 2:
    # aqui sabemos que (x,y) está na boca
    dentro = False
elif -4 <= x <= -1 and 4 <= y <= 7:
    # aqui sabemos que (x,y) está no olho esquerdo
    dentro = False
    if -3 < x < -2 and 5 < y < 6:
        # aqui sabemos que na verdade (x,y) está na íris esquerda
        dentro = True
elif  1 <= x <=  4 and 4 <= y <= 7:
    # aqui sabemos que (x,y) está no olho direito
    dentro = False
    if  2 < x <  3 and 5 < y < 6:
        # aqui sabemos que na verdade (x,y) está na íris direita
        dentro = True

if dentro:
    print("dentro")
else:
    print("fora")



#--------------------------------------------------------------------
# SOLUÇÃO 2: começa supondo que está fora e depois...
#     A variável dentro e um indicador de passagem bool.
#
#--------------------------------------------------------------------

x = float(input("Digite x: "))
y = float(input("Digite y: "))

# suponha que (x,y) está fora
dentro = False

if -5 < x < 5 and 0 < y < 8:
    # aqui sabemos que (x,y) está na face
    dentro = True
    if -3 <= x <= 3 and 1 <= y <= 2:
        # aqui sabemos que (x,y) esta na face, mas está na boca
        dentro = False
    elif -4 <= x <= -1 and 4 <= y <= 7:
        # aqui sabemos que (x,y) está no olho esquerdo
        dentro = False
        if -3 < x < -2 and 5 < y < 6:
            # aqui sabemos que na verdade (x,y) está na íris esquerda
            dentro = True
    elif  1 <= x <=  4 and 4 <= y <= 7:
        # aqui sabemos que (x,y) está no olho direito
        dentro = False
        if  2 < x < 3 and 5 < y < 6:
            # aqui sabemos que na verdade (x,y) está na íris direita
            dentro = True

if dentro:
    print("dentro")
else:
    print("fora")



#--------------------------------------------------------------------
# SOLUÇÃO 3. explora a simetria em relação ao eixo y.
#     A variável x_pos pode ser trocada por x.      
#     A variável dentro e um indicador de passagem bool.
#--------------------------------------------------------------------

x_pos = x = float(input("Digite x: "))
y = float(input("Digite y: "))

if x < 0: # simetria ;-)
    x_pos = -x

# suponha que (x,y) que está dentro
dentro = True

if x_pos >= 5 or y >= 8 or y <= 0:
    # aqui sabemos que (x,y) está fora da face
    dentro = False
elif 0 <= x_pos <= 3 and 1 <= y <= 2:
    # aqui sabemos que (x,y) está na boca
    dentro = False
elif 1 <= x_pos <= 4 and 4 <= y <= 7:
    # aqui sabemos que (x,y) está em um olho
    if not (2 < x < 3 or 5 < y < 6):
        # aqui sabemos que (x,y) está fora da íris
        dentro = False

if dentro:
    print("dentro")
else:
    print("fora")
 

#--------------------------------------------------------------------
# SOLUÇÃO 4: idêntica a anterior, explora simetria e um string para a 
#     resposta. A variável x_pos pode ser trocada por x.      
#     A variável dentro e um indicador de passagem str 
#     (hmmm, gosto discutível...).
#--------------------------------------------------------------------

x_pos = x = float(input("Digite x: "))
y = float(input("Digite y: "))

if x < 0: # simetria ;-)
    x_pos = -x

# suponha que (x,y) que está dentro
resposta = "dentro"

if x_pos >= 5 or y >= 8 or y <= 0:
    # aqui sabemos que (x,y) está na face
    resposta = "fora"
elif 0 <= x_pos <= 3 and 1 <= y <= 2:
    # aqui sabemos que (x,y) está na boca
    resposta = "fora"
elif 1 <= x_pos <= 4 and 4 <= y <= 7:
    # aqui sabemos que (x,y) está em um olho
    if not (2 < x < 3 or 5 < y < 6):
        # aqui sabemos que (x,y) está fora de uma íris
        resposta = "fora"

print(resposta)

#--------------------------------------------------------------------
# SOLUÇÃO 5: utiliza uma variável bool para indicar em qual quer 
#     da figuracada parte da face está o ponto: face, boca
#     olho direito, olho esquerdo, íris do olho direito, íris do olho 
#     esquerdo. A condição para decidir se o ponto está ou não 
#     na região hachurada pode parecer complicada, mas é bem elegante.
#--------------------------------------------------------------------

x = float(input("Digite x: "))
y = float(input("Digite y: "))

# face == True se (x,y) está na face, False em caso contrário
face = -5 < x < 5 and 0 < y < 8 

# boca == True se (x,y) está na boca, False em caso contrário
boca = -3 <= x <= 3 and 1 <= y <= 2

# olho_esquerdo == True se (x,y) está no olho esquerdo
olho_esquerdo = -4 <= x <= -1 and 4 <= y <= 7

# íris_esquerda == True se (x,y) está na íris esquerda
íris_esquerda = -3 <= x <= -2 and 5 <= y <= 6

# olho_direito  == True se (x,y) está no olho direito
olho_direito = 1 <= x <= 4 and 4 <= y <= 7

# íris_direita  == True se (x,y) está na íris direita
íris_direita = 2 <= x <= 3 and 5 <= y <= 6

# vixe! :-D complicado? certamente elegante...
if íris_esquerda or íris_direita or face and not (boca or olho_esquerdo or olho_direito):
    print("dentro")
else:
    print("fora")


#--------------------------------------------------------------------
# SOLUÇÃO 6: idêntica a anterior, mas explora a simetria como a 
#     solução 4.
#
#--------------------------------------------------------------------

x_pos = x = float(input("Digite x: "))
y = float(input("Digite y: "))

if x < 0:
    x_pos = -x 

# face == True se (x,y) está na face
face = x_pos <  5 and 0 < y < 8 

# boca == True se (x,y) está na boca
boca = x_pos <= 3 and 1 <= y <= 2

# olho == True se (x,y) está em um dos olhos
olho = 1 <= x_pos <= 4 and 4 <= y <= 7

# íris == True se (x,y) está em uma das íris
íris = 2 <= x_pos <= 3 and 5 <= y <= 6

# vixe! :-D complicado?! certamente muito elegante
if íris or face and not (boca or olho):
    print("dentro")
else:
    print("fora")

QUESTÃO 2

      Escreva um programa que lê dois inteiros m e n, 0 < m < n, e determina quantos inteiros entre m e n, escritos sem 0 à esquerda, não têm dígitos repetidos. Exemplos:

SOLUÇÃO


#--------------------------------------------------------------------
# DEBUG é uma variável usada durante a fase de teste
# NÃO FAZ PARTE DA SOLUÇÃO DA QUESTÃO
#
#   DEBUG = True para programa imprimir valores calculados
#   DEBUG = False para programa ser executado "silenciosamente"
#
# Sugerimos que você faça algo semelhante durante o desenvolvimento
# dos seus programas
#-------------------------------------------------------------------- 

#--------------------------------------------------------------------
# SOLUÇÃO 1: Contém laços encaixados (while).
#            Usa variáveis booleanas (valores True e False).
#
#--------------------------------------------------------------------
# texto em cinza, como este, não faz parte da solução
DEBUG = True

m = int(input("Digite m: "))
n = int(input("Digite n: "))

if DEBUG:
    print("------------------------------------------------")
    print("INICIO DEBUG:")

# teste todos o valores de 'candidado' entre m e n inclusive 
cont        = 0 # contador de número sem dígitos repetidos
candidato   = m
while candidato <= n:

    # para dígito = 0,1,2,3..,9, conte o número de ocorrência do
    # dígito em 'candidato' 
    tem_dígitos_repetidos = False
    dígito = 0
    while dígito < 10 and not tem_dígitos_repetidos: 
        # not tem_dígitos_repetidos é equivalente a 
        #     tem_dígitos_repetidos == False

        # conte o número de ocorrências de dígito em num
        cont_dígito = 0 
        num = candidato
        while num > 0:
            dígito_num = num % 10
            if dígito_num == dígito:
                cont_dígito += 1
            num //= 10

        if DEBUG:
            print("%d ocorre %d vezes em %d" 
                  %(dígito,cont_dígito,candidato))

        # se dígito ocorreu mais de uma vez, tem dígitos repetidos
        if cont_dígito > 1:
            tem_dígitos_repetidos = True

        # teste o próximo dígito
        dígito += 1

    if not tem_dígitos_repetidos:
        cont += 1
        if DEBUG:
            print(">>> %d não tem digitos repetidos" %(candidato))

    # teste o próximo candidato 
    candidato += 1

if DEBUG:
    print("FIM DEBUG")
    print("------------------------------------------------")

print("\nEntre", m, "e", n, "há", cont, "números sem dígitos repetidos"),



#--------------------------------------------------------------------
# SOLUÇÃO 2: Idêntica a solução anterior. Usa uma função e o programa
#            principal está dentro da função main().
#
#--------------------------------------------------------------------
# texto em cinza, como este, não faz parte da solução
DEBUG = True

#--------------------------------------------------------------------  
# Programa principal
# 
def main():
    m = int(input("Digite m: "))
    n = int(input("Digite n: "))

    if DEBUG:
        print("------------------------------------------------")
        print("INICIO DEBUG:")

    # teste todos o valores de 'candidado' entre m e n inclusive 
    cont        = 0 # contador de número sem dígitos repetidos
    candidato   = m
    while candidato <= n:
        if not tem_dígitos_repetidos(candidato):
            cont += 1
            if DEBUG:
                print("main: >>> %d não tem digitos repetidos" %(candidato))

        # teste o próximo candidato 
        candidato += 1

    if DEBUG:
        print("FIM DEBUG")
        print("------------------------------------------------")

    print("\nEntre", m, "e", n, "há", cont, "números sem dígitos repetidos"),



#--------------------------------------------------------------------  
def tem_dígitos_repetidos(número):
    ''' (int) -> bool

    Recebe um número inteiro positivo e retorna True se
    existe algum dígito que ocorre pelo menos duas vezes 
    em número. Não são considerados os zeros à esquerda

    >>> tem_dígitos_repetidos(12345)
    False
    >>> tem_dígitos_repetidos(12341)
    True
    >>> tem_dígitos_repetidos(12315)
    True
    '''

    achou_dígito_repetido = False

    # para todo dígito entre 0 e 9 conte o número de ocorrência do
    # dígito em 'número' 
    dígito = 0
    while dígito < 10 and not achou_dígito_repetido: 
        # conte o número de ocorrências de dígito em número
        cont_dígito = 0
        num = número # não podemos destruir número
        while num > 0:
            dígito_num = num % 10
            if dígito_num == dígito:
                cont_dígito += 1
            num //= 10

        if DEBUG:
            print("tem_dígitos_repetidos: %d ocorre %d vezes em %d" 
                  %(dígito,cont_dígito,número))

        # se dígito ocorreu mais de uma vez, tem dígitos repetidos
        if cont_dígito > 1:
            achou_dígito_repetido = True

        # teste o próximo dígito
        dígito += 1

    return achou_dígito_repetido     


#-----------------------------------------------------------
# início da execução do programa: chamada da função main()
main()


#--------------------------------------------------------------------
# SOLUÇÃO 3: Idêntica a solução anterior. Usa duas funções e o programa
#            principal está dentro da função main().
#
#--------------------------------------------------------------------
# texto em cinza, como este, não faz parte da solução
DEBUG = False

#--------------------------------------------------------------------  
# Programa principal
#
def main():
    m = int(input("Digite m: "))
    n = int(input("Digite n: "))

    if DEBUG:
        print("------------------------------------------------")
        print("INICIO DEBUG:")

    # teste todos o valores de 'candidado' entre m e n inclusive 
    cont        = 0 # contador de número sem dígitos repetidos
    candidato   = m
    while candidato <= n:
        if not tem_dígitos_repetidos(candidato):
            cont += 1
            if DEBUG:
                print("main: >>> %d não tem digitos repetidos" %(candidato))

        # teste o próximo candidato 
        candidato += 1

    if DEBUG:
        print("FIM DEBUG")
        print("------------------------------------------------")

    print("\nEntre", m, "e", n, "há", cont, "números sem dígitos repetidos"),



#--------------------------------------------------------------------  
def tem_dígitos_repetidos(número):
    ''' (int) -> bool

    Recebe um número inteiro positivo e retorna True se
    existe algum dígito que ocorre pelo menos duas vezes 
    em número. Não são considerados os zeros à esquerda 

    >>> tem_dígitos_repetidos(12345)
    False
    >>> tem_dígitos_repetidos(12341)
    True
    >>> tem_dígitos_repetidos(12315)
    True
    '''

    # teste se algum dígito entre 0 e 9 ocorre número mais que uma vez
    dígito = 0
    while dígito < 10: 
        # se dígito ocorreu mais de uma vez, tem dígitos repetidos
        if conta_dígitos(número,dígito) > 1:
            return True

        dígito += 1 

    # se chegou aqui não há dígito repetido
    return False


#--------------------------------------------------------------------  
def conta_dígitos(número, dígito):
    ''' (int, int) -> int

    Recebe um número inteiro positivo e um dígito e retorna
    o número de ocorrências do dígito no número.
    Não são considerados os zeros à esquerda

    >>> conta_dígitos(1213456,1)
    2
    >>> conta_dígitos(1213456,2)
    1
    >>> conta_dígitos(1213456,7)
    0
    '''

    # conte o número de ocorrências de dígito em número
    cont_dígito = 0
    num = número # não podemos destruir número
    while num > 0:
        dígito_num = num % 10
        if dígito_num == dígito:
             cont_dígito += 1
        num //= 10

    if DEBUG:
        print("conta_dígito: %d ocorre %d vezes em %d" 
               %(dígito,cont_dígito,número))

    return cont_dígito    
    
#-----------------------------------------------------------
# início da execução do programa: chamada da função main()
main()

QUESTÃO 3

      Um número é palíndromo se permanece igual se os dígitos forem reescritos da direita para esquerda (os números são escritos sem 0 à esquerda). Por exemplo, 5, 121, 12344321 são palíndromos, mas 10, 1210, 1233 não são. A função booleana abaixo decide se um número é palíndromo (se não entender como ela funciona, tanto faz, ela vem com garantia).

def palindromo(n):
    """ (int) --> bool
    Recebe um número inteiro n maior que zero e retorna
    True se o número é palíndromo e False em caso contrário.
    """

    N = n
    reflexo = 0
    while n > 0 :
        reflexo = 10*reflexo + n%10
        n = n//10
    return reflexo == N

      Escreva um programa que lê um número n, e uma sequência de n inteiros, e devolve o tamanho do maior segmento da sequência constituído exclusivamente de palíndromos. Por exemplo, para n = 12 e a sequência

    13  321  333  456  765  7777  8998  909  32  34  112211  323
há três segmentos formados por palíndromos:
    333

    7777 8998 909

    112211 323 ,
e o mais comprido tem tamanho 3, que é o valor a ser impresso.

      No seu programa, você deve usar a função palindromo; só usar, não copie o código da função.

SOLUÇÃO

#--------------------------------------------------------------------
# SOLUÇÃO 1: 
#            
#
#--------------------------------------------------------------------

n = int(input("Digite o tamanho da sequência: "))

maior_comprimento = 0 # maior comprimento de um segmento de palíndromos
comprimento_atual = 0 # comprimento do segmento sendo examinado
i = 0 # contador de números lidos
while i < n:
    num = int(input("Digite um número: "))

    if palindromo(num):
        # cresce o comprimento da segmento atual
        comprimento_atual += 1 
    else:
        comprimento_atual = 0

    # verifique se comprimento do segmento atual é o maior até o momento
    if comprimento_atual > maior_comprimento:
        maior_comprimento = comprimento_atual

    i += 1

print("O maior comprimento se um segmento de palíndromos é =", 
         maior_comprimento)

 

 

 


Last modified: Wed Apr 2 09:48:14 BRT 2014