9.1 Revisitando o cálculo do fatorial, recursivo e interativo
Agora que aprendemos a fazer também repetições com o comando while, sempre é bom pensar em qual o comando mais adequado. Vejamos o exemplo abaixo com duas versões da função para o cálculo do Fatorial.
functionfatorial_recursivo(n::Int64) # Com o ::Int64 estamos definindo que o parâmetro da função deve ser um número inteiro# Caso base do fatorial: 0! e 1! são iguais a 1if n ==0|| n ==1return1# Chamada recursiva: n! = n * (n-1)!elsereturn n *fatorial_recursivo(n -1)endendfunctionfatorial_iterativo(n::Int64)# Inicializa o resultado como 1 (já que o fatorial de 0 é 1) resultado =1# No loop estamos fazendo a multiplicação: n * (n-1) * ... * 2while n >1# Multiplica o resultado pelo valor atual de n resultado *= n# Decrementa n em 1 para continuar o cálculo do fatorial n -=1endreturn resultadoendprintln(fatorial_recursivo(3))
6
No código acima temos uma novidade, nos parâmetros da função, o tipo está sendo declarado expicitamente. No caso, estamos dizendo que o valor n que a função vai receber é de um tipo específico. Ou seja um Inteiro de 64 bits.
O estilo de código está um pouco diferente do que antes, pois foi escrito por outra pessoa. A monitora. Vemos que ela tem o hábito de usar nomes de variáveis maiores além do que usar contrações como += e *=.
9.2 Aproximação da raiz quadrada
Para o próximo exemplo, vamos ver o método de Newthon-Raphson para o cálculo da raiz quadrada. É um método recursivo no qual o próximo valor é baseado no valor anterior. Quanto mais chamadas forem feitas, mais próximo do valor final vai se chegar.
Mais informações sobre o método podem ser encontradas em aqui. Mas para o momento temos que pensar na seguinte implementação. Para se calcular a raiz, podemos usar a seguinte fórmula, a partir de um palpite inicial r, para o valor da raiz de x.
\[ r_{n+1} = 0.5 * (r + x / r)\]
Como o código abaixo é mais complicado, foram usados comentários.
functionaproxima_raiz(x::Float64, epsilon::Float64)::Float64if x <0returnnothingend# Chute inicial aproximacao = x/2 melhor_aproximicao = aproximacaowhiletrue# Fórmula para aproximação de raiz quadrada utilizando o método de Newthon-Raphson melhor_aproximicao =0.5* (aproximacao + x/aproximacao)# Se a distância absoluta entre os dois pontos é menor do que epsilon, então podemos parar o métodoifabs(aproximacao - melhor_aproximicao) <= epsilonbreakend# Se a aproximação ainda não for boa o sufuciente, então atualizamos a aproximação para a próxima iteração aproximacao = melhor_aproximicaoendreturn melhor_aproximicaoend
aproxima_raiz (generic function with 1 method)
Notem que foi introduzido um comando novo, o break, esse comando apenas interrompe a execução do while. Ou seja, força a saída do laço.
9.3 Verificar se um número é primo
No próximo exemplo, vamos verificar se um número é primo, ou seja, se os seus únicos divisores são 1 e o próprio. A forma mais simples de se fazer isso é procurando dividir o número por outros. Se algum dividir, o número não é primo.
functionverifica_primo(num :: Int64)if num <=1returnfalseend i=2# pode ser melhorado com i<=num/2# ou também com i<= sqrt(num): baseado no fato que um número composto deve ter um fator menor ou igual a raiz desse númerowhile i<numif num % i ==0returnfalseend i+=1endreturntrueend
verifica_primo (generic function with 1 method)
Assim, como o comando break é usado para interromper a execução de um laço, o comando return, pode ser usado para terminar a execução de uma função, a qualquer momento.
9.4 Verificar se um número é palíndromo
Um número palíndromo é um número que é simétrico. Ou seja, a leitura dos dígitos da esquerda para a direita é igual a leitura dos dígitos na ordem inversa. Por exemplo, o número 121 é palíndromo, assim como o 11 e o 25677652. Os números de um dígito também são.
functione_palindromo(n::Int64)#= Guarda os dígitos de n que ainda devem ser invertidos A variável auxiliar é necessária para que o valor de n não seja, perdido, e possamos usar ele posteriormente. =# aux = n# Guarda a inversão do número n n_inv =0#= Continuamos o while enquanto ainda há números a serem invertidos, ou seja, enquanto aux for maior que 0. =#while aux >0# Coloca o último dígito de aux na variável que guarda a inversão resto = aux %10 n_inv= n_inv *10+ resto# Retira o último dígito de aux aux =div(aux,10)endif n == n_invprintln("O número $n é palíndromo")elseprintln("O número $n não é palíndromo")endende_palindromo(2002)e_palindromo(1234)
O número 2002 é palíndromo
O número 1234 não é palíndromo