Exercício 01: Crie uma função que determine se um número é um palíndromo.
Por definição, um número palíndromo é aquele que, ao inverter seus dígitos ele permanece igual. Ex.:
$$12321, 535, 212,$$Crie primeiro uma função que receba um número $x$ como parâmetro e retorne esse número invertido. Faça primeiro o procedimento passo a passo no papel.
In [1]:
print (Palindromo(1221))
print (Palindromo(121))
print (Palindromo(1231))
Exercício 02: Crie uma função Fatorial() que calcule n!.
$$n! = n \cdot (n-1) \cdot (n-2) \dots 1$$Pense primeiro nos casos $0!$ e $1!$ antes de criar o algoritmo.
In [26]:
print (Fatorial(0))
print (Fatorial(1))
print (Fatorial(5))
print (Fatorial(10))
Exercício 03: Crie uma função para calcular o $n$-ésimo termo da sequência de Fibonacci.
A sequência de Fibonacci é definida por:
$$ F_0 = F_1 = 1 \\ F_n = F_{n-1} + F_{n-2} $$
In [5]:
for i in range(10):
print (Fibonacci(i),)
print()
Exercício 04: Crie uma função SomaSerie()
que efetue a soma $S$ das seguintes séries para um valor de $n$:
In [8]:
print (SomaSeries(3))
print (SomaSeries(10))
print (SomaSeries(100))
Exercício 05: Crie 2 funções para calcular o Coeficiente Binomial:
$$\binom nk = \frac{n!}{k!\,(n-k)!} \quad \text{for }\ 0\leq k\leq n.$$Na primeira versão, utilize a função fatorial do Exercício 02.
Na segunda versão, tente simplificar ao máximo a equação para reduzir o número de operações efetuadas.
In [25]:
print (Binomial1(4,2), Binomial2(4,2))
print (Binomial1(10,4), Binomial2(10,4))
Exercício 06: Crie uma função para verificar o paradoxo de Monty Hall.
O Paradoxo de Monty Hall mostra como o cálculo de probabilidades pode ser contra-intuitivo.
Monty Hall é um programa de auditório em que, em um dos jogos, o particpante deve escolher uma entre três portas.
Uma dessas portas contém um carro, as outras duas, uma cabra.
Após o participante realizar a escolha, o apresentador abre uma das duas outras portas revelando uma cabra. Então ele pergunta: "Você gostaria de mudar de porta?".
Qual a escolha que tem maior probabilidade de vitória? Manter a escolha atual ou mudar de porta?
O paradoxo diz que, inicialmente ao escolher uma das portas a probabilidade de acertar é 1/3, e a de errar 2/3. Após ser revelado uma das portas erradas, as probabilidades se mantêm, então ao mudar de porta ele terá probabilidade de 2/3 de vitória.
Faça uma função que simule $n$ partidas desse jogo, mantendo a escolha de porta inicial e $n$ partidas alterando a porta. Estime a probabilidade de vitória nos dois casos.
Para simular o sorteio de qual porta tem o prêmio e qual porta o participante escolhe, utilize a função randint(a,b)
da biblioteca random
. Essa função retorna um número aleatório $n$ tal que $a \leq n \leq b$.
In [12]:
import random
print(MontyHall(100))
Exercício 07: Dado um número $x$, crie a função Segmenta()
que divida esse número em segmentos de $d$ dígitos. Ex.:
Note que é mais fácil extrair os $d$ dígitos da direita para a esquerda. Nesse caso, crie também uma função Inverte()
que gera o inverso de um número.
Crie então uma outra função chamada Crescente()
que verifica se a lista de valores estão em ordem crescente.
Finalmente, crie uma função que verifique qual o menor valor de $d$ que gera um segmento de números crescentes.
In [23]:
print (MenorD(131145))
Exercício 08: Faça uma função que gere o triângulo de Pascal.
Ele é composto por $N$ listas, sendo que cada lista $i$ tem tamanho $i+1$ com $i=0 \dots N-1$.
O elemento da linha $i$ e coluna $j$ pode ser calculado através do coeficiente binomial $\binom{i}{j}$ ou somando os elementos $i-1,j-1$ com $i-1,j$, assumindo $0$ quando fora do limite.
Para armazenar o triângulo, você terá que criar lista de listas. Ex.:
In [29]:
lista = [] # lista vazia
lista.append( [0,1]) # insere uma lista dentro da lista
print (lista)
lista.append([2,3,4])
print (lista)
print (lista[0])
print (lista[1][2])
In [28]:
for l in Pascal(5):
print (l)
Exercício 09: Um Fractal é uma imagem com padrões auto-similares. Uma forma de desenhar um fractal é através do Conjunto Julia, que trabalha com números complexos. Podemos construir uma matriz com valores do conjunto de Julia da seguinte forma:
m = []
Para i de -1.5 até 1.5 com passo p:
l = []
Para j de 1.0 até -1.0 com passo -p:
l.append( Julia( complex(i,j), c ) )
m.append(l)
Para percorrermos os valores em uma faixa de números reais, podemos utilizar o comando arange()
da biblioteca numpy
:
import numpy as np
m = []
for i in np.arange(-1.5,1.5,p):
l = []
for j in np.arange(1.0,-1.0,-p):
l.append( Julia( complex(i,j), c ) )
m.append(l)
Ou usando syntatic sugar:
m = [ [Julia(complex(i,j),c) for j in np.arange(1.0,-1.0,-step)] for i in np.arange(-1.5,1.5, step) ]
O comando complex()
cria um número complexo através dos valores passados como parâmetro. A variável $c$ é um número complexo de base passada como parâmetro.
A função Julia(x,y)
é definida como:
range(200)
Implemente a função Julia(x,y)
e a função GeraFractal(c, passo )
que recebe o número complexo semente e o tamanho do passo.
Essa função deve gerar a tal matriz m, os comandos para plotagem já são dados!
Não utilize um passo menor que 0.005, pois poderá ocupar muita memória do computador.
Experimente com diversos valores de $c$.
In [3]:
%pylab inline
import matplotlib.pylab as plt
import numpy as np
def Julia(x,y):
...
return n
def GeraFractal( c, step ):
m = [ [Julia(complex(i,j),c) for j in np.arange(1.0,-1.0,-step)] for i in np.arange(-1.5,1.5, step) ]
fig = plt.figure(figsize=(15,15))
plt.imshow(m, cmap="RdGy", extent=[-2,2,-2,2])
GeraFractal(-0.06+0.67j, 0.005)
Exercício 10: A música We Will Rock You do grupo Queen inovou na criação de uma técnica de mixagem hoje conhecida como reverberação não-harmônica.
Para criar o efeito de uma multidão, o guitarrista e físico Brian May, gravou o efeito de batida e multiplicou essas batidas com pequenos atrasos.
Para evitar que as múltiplas cópias se sobrepusessem, ele fez com que os atrasos fossem múltiplos de números primos.
Vamos utilizar para essa tarefa as bibliotecas wave
e audioop
do Python e o som Palmas.wav fornecido no site do curso.
A primeira tarefa é criar uma função Primo(n)
que verifica se o número $n$ é primo.
A segunda tarefa é completar a função GeraMusica( ecos )
que gera $n$ repetições do som contido no arquivo, com $n$ sendo a quantidade de números primos de 1 até ecos.
In [288]:
import wave, audioop
def GeraMusica( ecos ):
# abre o arquivo fornecido
som1 = wave.open('Palmas.wav')
# criar o arquivo destino, o segundo parâmetro 'w'
# indica que o arquivo vai ser aberto para escrita
som2 = wave.open('WeWillRockYou.wav', 'w')
# faz com que o som criado tenha os mesmos parâmetros do som original
som2.setnchannels( som1.getnchannels() )
som2.setsampwidth( som1.getsampwidth() )
som2.setframerate( som1.getframerate() )
# lê o arquivo de audio e normaliza o som
frames = som1.readframes( som1.getnframes() )
taxa = 0x7fff/ audioop.max(frames, som1.getsampwidth())
frames = audioop.mul(frames, som1.getsampwidth(), taxa)
# gera uma lista de números primos de 1 até ecos
primos = ???
# o som está em 44100Hz com apenas 1 canal, isso significa
# que cada decimo de segundo contem 44100/10 posições da lista
# cada eco será colocado com atraso de mult*p, onde p é cada número primo
mult = som1.getframerate()*som1.getnchannels()/10
# cada eco tem um decaimento de amplitude
decaimento = 0.3
# para cada numero primo
for p in primos:
# a partir de onde começaremos a colocar o eco
atraso = ???
# frame2 será o trecho que copiaremos para o eco
# ele sera o conteúdo da lista frames do elemento 0 até len()-atraso
frame2 = ???
# Vamos multiplicar frame2 pelo decaimento, para reduzir o som
frame2 = audioop.mul( frame2, som1.getsampwidth(), decaimento)
# frame2 será adicionado a frames a partir do atraso
# utilize a função audioop.add( frame1, frame2, som1.getsampwidth() )
frame1 = ???
frame2 = audioop.add( frame1, frame2, som1.getsampwidth())
# concatene frames de 0 até atraso com frame2
frames = ???
# reduza o decaimento pela metade
decaimento = ???
# grava o novo som
som2.writeframes( frames )
som1.close()
som2.close()
GeraMusica(100)
In [ ]: