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

MAC2166 Introdução à Computação

Escola Politécnica - Primeiro Semestre de 2013

Prova 2


QUESTÃO 1

      Esta questão é composta por 3 itens. Assuma que as funções e programa a serem escritos estão todos em um mesmo arquivo, sem a necessidade de importação de módulos.

item (a)
Para um inteiro r ≥ 0, denote por Kr o número

1 - 1/3 + 1/5 - . . . + -1r/(2r+1).
Assim, por exemplo, K0 = 1, K1 = 2/3 = 0.6666..., K2 = 13/15 = 0.8666... e K3 = 76/105 = 0.7238....

Escreva uma função de cabeçalho

          def K(r):
que recebe como parâmetro um inteiro r ≥ 0 e retorna o valor de Kr.

SOLUÇÃO


#--------------------------------------------------------------------
# SOLUÇÃO 1: 
#            
#--------------------------------------------------------------------
def K(r):
    ''' (int) -> float

    Recebe um número inteiro r >= 0 e retorna o valor da função
    K, como definida a qusetão, calculada em r.

    >>> K(0)
    1
    >>> K(1)
    0.6666666666666667
    >>> K(2)
    0.8666666666666667
    '''

    K_r = 0
    for i in range(r+1):
        # -1**i é errado e feio... (-1)**i só é feio...
        termo = (-1)**i/(2*i+1) 
        K_r   = K_r + termo

    return K_r



#--------------------------------------------------------------------
# SOLUÇÃO 2: 
#            
#--------------------------------------------------------------------
def K(r):
    ''' (int) -> float

    Recebe um número inteiro r >= 0 e retorna o valor da função
    K, como definida a qusetão, calculada em r.

    >>> K(0)
    1
    >>> K(1)
    0.6666666666666667
    >>> K(2)
    0.8666666666666667
    '''

    K_r         = 1
    numerador   = 1
    denominador = 1
    for i in range(r):
        numerador    = -numerador  
        denominador  = denominador + 2 
        K_r          = K_r + numerador/denominador

    return K_r

item (b)
Considere a função, definida para todo x com |x| < 1, dada pela série

f(x) = = (x2/2)K0+ (x6/6)K1+ (x10/10) K2 + . . . + (x4r+2/(4r+2)) Kr + . . .
Escreva uma função de cabeçalho
          def f(x,eps):
que recebe como parâmetro um real x tal que |x| e calcula uma aproximação de f(x) dada pela série acima, incluindo na soma todos os termos até o primeiro de valor menor que eps. O primeiro termo de valor menor que eps DEVE ser incluído na soma. A função deve retornar o valor da aproximação e o valor do último termo incluído na aproximação, nesta ordem.
Utilize obrigatoriamente a função do item anterior, mesmo que você não a tenha feito.

SOLUÇÃO


def f(x,eps): 
    '''(float,float) -> float, float

    Recebe x e eps e calcula uma aproximação de f(x) "com
    precisão eps" e retorna o valor da aproximação e o último
    termo incluído na aproximação.

    >>> f(1,0.1)
    aprox = 0.500000 termo = 0.500000
    aprox = 0.611111 termo = 0.111111
    aprox = 0.697778 termo = 0.086667
    (0.6977777777777778, 0.08666666666666667)
    >>> f(0.5,0.01)
    aprox = 0.125000 termo = 0.125000
    aprox = 0.126736 termo = 0.001736
    (0.1267361111111111, 0.0017361111111111112)
    ''' 

    r           = 0 
    denominador = 2
    pot_x       = x*x
    termo       = pot_x * K(0)/ denominador
    aprox       = termo
    # linha a seguir não faz parte da solução 
    print("aprox = %f termo = %f" %(aprox,termo))
    while termo >= eps: # equivalente a abs(termo) >= eps, pois
                        # termo é sempre >= 0
        r           = r + 1                
        denominador = denominador + 4 # equivalente a denominador = 4*r + 2 
        pot_x       = pot_x * x**4    # equivalente a pot_x = x**denominador
        termo       = pot_x * K(r) / denominador
        aprox       = aprox + termo
        # linha a seguir não faz parte da solução 
        print ("aprox = %f termo = %f" %(aprox,termo))

    return aprox, termo

item (c)
Escreva um programa que lê um número real x, com |x|, um real eps>0, e imprime o valor da aproximação de f(x) e o último termo incluído na aproximação. Utilize obrigatoriamente a função do item anterior, mesmo que você não a tenha feito. O valor de eps deve ser usado na chamada dessa função.

SOLUÇÃO

def main():
    '''
    Programa que lê um número real x, |x|< 1, e lê um número
    real eps e imprime o valor da aproximação de f(x) e o último
    termo incluído na aproximação.
    '''

    x   = float(input("Digite o valor de x: "))
    eps = float(input("Digite o valor de eps: "))

    fx, termo = f(x,eps)

    print("Aproximação de f(%f)  = %f" %(x,fx))
    print("Último termo incluído = %f" %termo)

QUESTÃO 2

Escreva um programa que lê

O programa deve imprimir os números que aparecem nas duas sequências.

Por exemplo, para entrada

 
    6 
    4.1  -7.2  5.0  24.2  5.0  8
    4
    5.0   6.3  5.0  -7.2 
o programa deve imprimir
    O número 5.0 aparece nas duas sequências. 
    O número -7.2 aparece nas duas sequências. 

      Note que o número 5, que ocorre várias vezes nas duas sequências, deve ser impresso apenas uma vez.

Não se preocupe com o formato em que os números serão impressos.

Caso ache conveniente, escreva (e use) funções adicionais.

SOLUÇÃO


#--------------------------------------------------------------------
# SOLUÇÃO 1: utiliza o iterador "for variável in range(...): ..."
#            constrói a intersecção das listas e depois
#            cosntrói a intersecção das lista sem repetições
#--------------------------------------------------------------------
def main():
    '''
    Programa que lê:
    
       * um inteiro positivo m,
       * uma sequência com m números reais
       * um inteiro positivo n,
       * uma lista com n números reais

    e imprime, sem repetições, os números que ocorrem nas
    duas sequências.
    '''

    # leia as duas sequências
    lista1 = le_sequência()
    lista2 = le_sequência()
    m = len(lista1)
    
    # calcule a intersecção das duas listas
    inter = []
    for i in range(m):
        if ocorre(lista1[i],lista2):
            inter.append(lista1[i])

    # remova as repetições
    inter_sem_repetições = []
    for i in range(len(inter)):
        if not ocorre(inter[i],inter_sem_repetições):
            inter_sem_repetições.append(inter[i])
        
    # imprima intersecção sem repetições
    for i in range(len(inter_sem_repetições)):
        print("O número", inter_sem_repetições[i], "ocorre nas duas sequências")
    
def le_sequência():
    '''() -> int, lista
    Função que lê um inteiro positivo n e uma sequência de n
    números reais e retorna uma lista contendo a sequência.
    '''

    n = int(input("Digite tamanho da sequência: "))
    lista = []
    for i in range(n):
        x = float(input("Digite um número da sequência: "))
        lista.append(x)
    return lista

def ocorre(x, lista):
    ''' (float,lista) -> bool
    Função que recebe um float x e uma lista e retorna True
    se x pertence a lista e False em caso contrário.
    '''
    
    n = len(lista)
    for i in range(n):
        if x == lista[i]:
            return True
    return False

# início do programa
main()



#--------------------------------------------------------------------
# SOLUÇÃO 2: utiliza o iterador "for variável in range(...): ..."
#            
#--------------------------------------------------------------------
def main():
    '''
    Programa que lê:
    
       * um inteiro positivo m,
       * uma sequência com m números reais
       * um inteiro positivo n,
       * uma lista com n números reais

    e imprime, sem repetições, os números que ocorrem nas
    duas sequências.
    '''

    # leia as duas sequências 
    lista1 = le_sequência()
    lista2 = le_sequência()
  
    # calcule a intersecção das duas listas sem repetições 
    inter = []
    m = len(lista1)
    for i in range(m):
        if ocorre(lista1[i],lista2):
            if not ocorre(lista1[i], inter): # não queremos repetições
                inter.append(lista1[i])

    # imprima a intersecção            
    for i in range(len(inter)):
        print("O número", inter[i], "ocorre nas duas sequências")
    
def le_sequência():
    '''() -> int, lista
    Função que lê um inteiro positivo n e uma sequência de n
    números reais e retorna uma lista contendo a sequência.
    '''

    n = int(input("Digite tamanho da sequência: "))
    lista = []
    for i in range(n):
        x = float(input("Digite um número da sequência: "))
        lista.append(x)
    return lista

def ocorre(x, lista):
    ''' (float,lista) -> bool
    Função que recebe um float x e uma lista e retorna True
    se x pertence à lista e False em caso contrário.
    '''
    
    n = len(lista)
    for i in range(n):
        if x == lista[i]:
            return True
    return False

# início do programa
main()

  
#--------------------------------------------------------------------
# SOLUÇÃO 3: utiliza o iterador "for elemento in lista: ..."
#            
#--------------------------------------------------------------------
def main():
    '''
    Programa que le:
    
       * um inteiro positivo m,
       * uma sequência com m números reais
       * um inteiro positivo n,
       * uma lista com n números reais

    e imprime, sem repetições, os números que ocorrem nas
    duas sequências.
    '''

    # leia as duas sequências
    lista1 = le_sequência()
    lista2 = le_sequência()

    # determine a intersecção das duas lista, sem repetições
    inter = []
    for x in lista1:
        if ocorre(x,lista2):
            if not ocorre(x, inter):# não queremos repetições
                inter.append(x)

    # imprima a intersecção das listas            
    for x in inter:
        print("O número", x, "ocorre nas duas sequências")
    
def le_sequência():
    '''() -> lista
    Função que lê um inteiro positivo n e uma sequência de n
    números reais e retorna uma lista contendo a sequência.
    '''

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

    # crie uma lista com os elementos da sequência
    lista = []
    for i in range(n):
        x = float(input("Digite um número da sequência: "))
        lista.append(x)
        
    return lista

def ocorre(x, lista):
    ''' (float,lista) -> bool
    Função que recebe um float x e uma lista e retorna True
    se x pertence à lista e False em caso contrário.
    '''
    
    for elem in lista:
        if x == elem:
            return True
    return False

Início da programa
main()


  
#--------------------------------------------------------------------
# SOLUÇÃO 3: 
#            
#--------------------------------------------------------------------

QUESTÃO 3

Esta questão é baseada no EP3. Suponha que todas as funções dadas e as que você precisa escrever estão em um mesmo arquivo --- para usar essas funções não há necessidade de importação de módulos.

item (a)
Escreva uma função com o cabeçalho

    def atualize_turtleship(turtleship, lista_astros, delta_t):
que recebe: Uma turtleship é representada através de uma lista que tem a forma
[[x_t,y_t], [vx_t,vy_t], cor_t, nome_t, ativa_t],
onde Esta função deve calcular a posição e velocidade da turtleship no instante t+delta_t e atualizá-las.

Dados a posição x, a velocidade v e a aceleração a num instante t, podemos calcular seus valores x', v' no instante seguinte t+Δt pelas fórmulas:

x' = x + v Δt + a (Δt)2/2,
v' = v + a Δt.

Na sua função, você deve usar a função a seguir sem escrevê-la (suponha que ela é dada):

     def aceleração_resultante(lista_astros, ponto):
que recebe em lista_astros uma lista de astros celestes e um ponto=[x,y] e retorna o vetor aceleração [a_x,a_y] da força gravitacional exercida pelos astros sobre um objeto no ponto.

SOLUÇÃO

def atualize_turtleship(turtleship, lista_astros, delta_t):
    '''(lista, lista, flota) -> None
    '''

    t = turtleship
    a_r = aceleração_resultante(lista_astros, t[0])
    t[0][0] += t[1][0]*delta_t + a_r[0]*delta_t*delta_t/2
    t[0][1] += t[1][1]*delta_t + a_r[1]*delta_t*delta_t/2
    t[1][0] += a_r[0] *delta_t
    t[1][1] += a_r[1] *delta_t

item (b)
Escreva uma função com o cabeçalho

    def simule(lista_astros, lista_turtleships, t_max, delta_t, d_colisão):
que recebe: e simula as trajetórias das 2 turtleships em lista_turtleships sob o efeito da força gravitacional exercida pelos astros em lista_astros.

O instante inicial da simulação é 0 e a cada passo da simulação o tempo de simulação é acrescido de delta_t. Uma turtleship colide com a outra se a distância entre elas for menor do que d_colisão. Caso haja colisão, imprima a seguinte mensagem: ``Colisão entre as tartarugas!''

Uma turtleship será desativada se ela colidir com algum astro ou se ela colidir com a outra turtleship. No caso de colisão com um astro, o tempo da simulação deverá ser impresso. Havendo colisão simultânea, entre as turtleships e entre uma turtleship e um astro, somente a colisão entre as turtleships deve ser informada.

As posições das turtleships ativas deverão ser atualizadas e impressas em cada passo da simulação.

A simulação termina quando o tempo de simulação ultrapassar t_max ou quando não houver nenhuma turtleship ativa (todas turtleships colidiram). Imprima uma mensagem indicando o motivo do término da simulação.

Na sua função, você deve usar as funções a seguir sem escrevê-las (suponha que elas são dadas):

     def distância(ponto_1, ponto_2):
que recebe dois pontos ponto_1=[x1,y1] e ponto_2=[x2,y2] e retorna a distância entre ponto_1 e ponto_2.
     def houve_colisão(turtleship, lista_astros):
que recebe uma turtleship e uma lista_astros e devolve True se a turtleship colidiu com algum astro e, em caso contrário, retorna False.

O uso das funções da biblioteca matemática é livre. Aqui vai uma pequena lista delas: cos(x), sin(x), hypot(x,y), pow(x,y), sqrt(x), tan(x), acos(x), asin(x) e atan(x). Caso use alguma dessas funções, não esqueça de importar o módulo matemático.

SOLUÇÃO

def simule(lista_astros,  lista_turtleships, t_max, delta_t, d_colisão):
    ''' (lista, lista, float, float, float) -> None
    '''  

    # inicialize o cronômetro
    t = 0
    
    #  número de turtleships ativas
    ativas = 2
    t0 = lista_turtleships[0]
    t1 = lista_turtleships[1]

    # enquanto o cronômetro não ultrapassar o tempo 
    # máximo de simulação e houver alguma turtleship ativa faça
    while t <= t_max and ativas > 0:
        # se a turtleship t0 está ativa
        if t0[4]:
            # atualize sua posição
            atualize_turtleship(t0, lista_astros, delta_t)

        # se a turtleship t1 está ativa    
        if t1[4]:
            # atualize sua posição 
            atualize_turtleship(t1, lista_astros, delta_t)

        # atualize o cronômetro
        t += delta_t

        # se as duas turtleships estão ativas
        if ativas == 2:
            # verifique se houve colisão entre as turtleships
            if distância(t0[0], t1[0]) < d_colisão:
                print("Colisão entre as tartarugas!")
                ativas = 0
                t0[4] = False
                t1[4] = False
                
        # se a turtleship t0 está ativa 
        if t0[4]:
            # verifique se t0 colidiu com algum astro
            if houve_colisão(t0, lista_astros):
                t0[4] = False
                ativas -= 1
                print("Colisão de turtleship no tempo", t)
                
        # se a turtleship t1 está ativa        
        if t1[4]:
            #verifique se t1 colidiu com algum astro
            if houve_colisão(t1, lista_astros):
                t1[4] = False
                ativas -= 1
                print("Colisão de turtleship no tempo", t)

    # mensagem indicando o(s) motivo(s) do término da simulação
    if t > t_max:
        print("Terminou o tempo da simulação.")
    if ativas == 0:
        print("Não há turtleship ativa.")

 

 

 


Last modified: Tue May 14 08:22:25 BRT 2013