Departamento de Ciência da
Computação - IME - USP
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 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.
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.
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)
Escreva um programa que lê
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 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:
#
#--------------------------------------------------------------------
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:
[[x_t,y_t], [vx_t,vy_t], cor_t, nome_t, ativa_t],onde
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.
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:
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.
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.")