Exercícios


Questão 1

Implemente de forma recursiva uma função que recebe como entrada um número natural \(n\) e retorna \(n!\).

Não esqueça de verificar se o argumento passado como entrada é realmente um número natural.

Fatorial_rec = function(n){
  if(!is.numeric(n))
    stop("o argumento de entrada tem que ser numérico.")
  if(n<0)
    stop("o argumento de entrada tem que ser um número não negativo")
  if(n == 0)
    return(1)
  return(n*Fatorial_rec(n-1))
}

Fatorial_rec(5)
## [1] 120

Questão 2

Implemente de forma recursiva uma função que recebe como entrada um vetor \(v\) e retorna o valor máximo desse vetor.

Maior_rec = function(v){
  if(!is.numeric(v))
    stop("o argumento de entrada tem que ser um vetor numérico.")
  n = length(v)
  if(n == 1)
    return(v[1])
  w = v[2:n]
  max_w = Maior_rec(w)
  if( v[1] > max_w){
    return(v[1])
  }
  return(max_w)
}

Maior_rec(c(0,21,9,1))
## [1] 21

Questão 3

No caderno escreva um pseudocódigo recursivo para o algoritmo que recebe como entrada um vetor \(v\) e retorna a soma dos elementos desse vetor.

Em seguida, no computador, implemente o pseudocódigo elaborado.

# Pseudo Código

# Entrada:v
# Saída: Soma dos elementos de v
# Nome: soma_rec

# 1. Caso v não seja numérico, retorne erro.
# 2. Defina n como o tamanho do vetor v;
# 3. Se n=1, retorne V[1];
# 4. Defina w = v[2:n]
# 5. Retorne (v[1] + soma_rec(w))
Soma_rec = function(v){
  if(!is.numeric(v))
    stop("o argumento de entrada tem que ser um vetor numérico.")
  n = length(v)
  if(n==1){
    return(v[1])
  }
  w = v[2:n]
  return( v[1] + Soma_rec(w) )
}

Soma_rec(c(0,21,9,1))
## [1] 31

Questão 4

No caderno escreva um pseudocódigo recursivo para o algoritmo que recebe como entrada um vetor \(v\) e retorna a posição onde se encontra o valor máximo desse vetor.

Dica: em vez de definir \(w=(v_2,v_3,…,v_n)\) defina \(w=(v_1,v_2,…,v_{n−1})\) para a chamada recursiva.

Mas cuidado que isso muda um pouco a forma de pensar. Em seguida, no computador, implemente o pseudocódigo elaborado.

# Pseudo Código

# Entrada:v
# Saída: Posição do maior elemento de v
# Nome: posicao_rec

# 1. Caso v não seja numérico, retorne erro.
# 2. Defina n como o tamanho do vetor v;
# 3. Se n=1, retorne V[1];
# 4. Defina w = v[2:n-1]
# 5. Defina pos_w = posicao_rec(w)
# 6. Se v[n] > v[pos_w], retorne n
# 6. Retorne (pos_w)
Posicao_rec = function(v){
  if(!is.numeric(v))
    stop("o argumento de entrada tem que ser um vetor numérico.")
  n = length(v)
  if(n == 1)
    return(1)
  w = v[1:n-1]
  pos_w = Posicao_rec(w)
  if( v[n] > v[pos_w]){
    return(n)
  }
  return(pos_w)
}

Posicao_rec( c(1,8,98,5,2) )
## [1] 3

Questão 5

Suponha que você vá investir R$ 500,00 na poupança e que esta rende 7,5% ao ano.

(a). Calcule na mão o quanto de dinheiro você teria no banco depois de 1, 2 e 3 anos de investimento.

# 1 Ano de investimento = 500 * (1 ^ 7,5% (ao ano)) = R$ 537,50
# 2 Anos de investimento = 500 * (2 ^ 7,5% (ao ano)) = R$ 577,80
# 3 Anos de investimento = 500 * (3 ^ 7,5% (ao ano)) = R$ 621,15

(b). Tente achar uma equação que relacione o total de dinheiro acumulado em \(n\) anos de investimento com o total de dinheiro acumulado em \(n_{−1}\) anos.

# Função: M = C(1+i)^t
# M = montante
# C = capital inicial
# i = taxa de juros
# t = tempo

(c). Usando a equação encontrada, no caderno escreva um pseudocódigo recursivo para o algoritmo que recebe como entrada um número natural \(n\) e retorna o dinheiro acumulado em \(n\) anos nesse investimento.

# Pseudo Código
# Entrada: n
# Saída: Xn = total acumulado após n meses de investimento, considerando juros de
# 0,75% e investimento incial de R$ 500,00.
# Nome: Investimento_rec

# 1. Caso n não seja inteiro não negativo, retorne erro.
# 2. Se n=0, retorne 500;
# 3. Retorne 1.075*Investimento_rec(n-1)

(d). Agora no computador implemente o pseudocódigo elaborado.

Investimento_rec = function(n){
  if(!is.numeric(n))
    stop("o argumento de entrada tem que ser numérico.")
  if(n<0)
    stop("o argumento de entrada tem que ser um número não negativo")
  if(n == 0){
    return(500)
  }
  return(1.075*Investimento_rec(n-1))
}

Investimento_rec(3)
## [1] 621.1484

Questão 6

Suponha que você vai fazer um financiamento de R$ 1.200,00 e vai pagar juros compostos de 2% ao mês.

Considere que você pode pagar R$ 150,00 por mês.

(a). Calcule na mão o valor da sua dívida depois de 1, 2 e 3 meses.

# 1 mês = (1 + 0.2% (ao mês) )*1200 - 150 = R$ 1.074,00
# 2 meses = (1 + 0.2% (ao mês) )*1074 - 150 = R$ 945,48
# 3 meses = (1 + 0.2% (ao mês) )*1945,48 - 150 = R$ 814,38

(b). Tente achar uma equação que relacione a sua dívida no mês \(n\) com a sua dívida no mês \(n_{−1}\).

# Função: Dn = J * Dn-1 - P
# Dn = Divida Total
# Dn-1 = Divida anterior
# J = Juros
# P = Prestação

(c). Usando a equação encontrada escreva no caderno um pseudocódigo recursivo para o algoritmo que recebe como entrada um número natural \(n\) e retorna a sua dívida após \(n\) meses do início do financiamento.

Não se esqueça de considerar o caso em que a dívida foi paga, nesse caso você deve retornar \(0\).

# Pseudo Código
# Entrada: n
# Saída: Xn = Total da divida após n meses , considerando juros de
# 0,2% ao mês e prestação de R$ 150,00.
# Nome: Divida_rec

# 1. Caso n não seja inteiro e não negativo, retorne erro.
# 2. Se n=0, retorne 1.200;
# 3. Faça D =  1.02*Divida_rec(n-1)-150;
# 4. Se D < 0 , returne 0, senão retorne D.

(d). Agora no computador implemente o pseudocódigo elaborado acima.

Divida_rec = function(n){
  if(!is.numeric(n))
    stop("o argumento de entrada tem que ser numérico.")
  if(n<0)
    stop("o argumento de entrada tem que ser um número não negativo")
  if(n == 0){
    return(1200)
  }
  D = 1.02*Divida_rec(n-1)-150
  if( D<0){
    return(0)
  } else{return(D)}
}

Divida_rec(1)
## [1] 1074
Divida_rec(2)
## [1] 945.48
Divida_rec(3)
## [1] 814.3896

Questão 7

Implemente uma função recursiva que recebe como entrada um número natural \(n\) e retorna o n-ésimo termo da sequência de Fibonacci.

Fibonacci_rec = function(n){
  if(n<=0 || (n%%1 != 0))
    stop("O argumento de entrada tem que ser um inteiro positivo.")
  if(n==1 || n==2){
    return(1)
  }
  return(Fibonacci_rec(n-1) + Fibonacci_rec(n-2))
}

Fibonacci_rec(10)
## [1] 55

Questão 8

Considere a seguinte sequência definida a partir de uma equação de diferenças de segunda ordem.

\(y_n = 2y_{n-1} + y_{n-2} + n \ \ \ \hbox{ com } \ \ \ y_1 = 0 \hbox{ e } y_2 = 0\)

(a). No caderno escreva um pseudocódigo recursivo para o algoritmo que recebe como entrada um número natural \(n\) e retorna o valor de \(y_n\).

# Pseudo Código
# Entrada: n
# Saída: Yn = valor da função Yn = 2y(n-1)+y(n-2)+n com y1=0 e y2=0.
# Nome: Equacao_rec
# 
# 1. Caso n não seja inteiro positivo, retorne erro.
# 2. Se n=1 ou n=2, retorne 0;
# 3. Defina o vetor y = (0,0);
# 4. Faça y[n] = 2*Equacao_rec(n-1) + Equacao_rec(n-2) + n;
# 5. Retorne y[n].

(b). Agora no computador implemente o pseudo-código elaborado acima.

Equacao_rec = function(n){
  if(n<=0 || (n%%1 != 0))
    stop("O argumento de entrada tem que ser um inteiro positivo.")
  y = c(0,0)
  if(n==1 || n==2){
    return(0)
  }
  y[n] = 2*Equacao_rec(n-1) + Equacao_rec(n-2) + n 
  return(y[n])
}

Equacao_rec(4)
## [1] 10

Questão 9

No caderno escreva um pseudocódigo recursivo para o algoritmo que recebe como entrada um array de números e retorna o número de elementos nulos nesse array.

Em seguida, no computador, implemente o pseudocódigo elaborado.

# Pseudo Código

# Entrada:v
# Saída: Total de elementos nulos
# Nome: Nulos_rec

# 1. Caso v não seja numérico, retorne erro.
# 2. Defina n como o tamanho do vetor v;
# 3. Se n=1 e v[1] for nulo, retorne 1, senão 0;
# 4. Defina w = v[2:n]
# 5. Defina contador = Nulo_rec(w)
# 6. Se v[1] for nulo, faça contador = contador + 1
# 7. Retorne (contador)
Nulos_rec = function(v){
  if(!is.numeric(v))
    stop("o argumento de entrada tem que ser um vetor numérico.")
  n = length(v)
  if(n == 1)
    if(is.na(v[1]) == FALSE){
      return(0)
    } else{return(1)}
  w = v[2:n]
  contador = Nulos_rec(w)
  if( is.na(v[1]) == TRUE){
    contador =  contador + 1
  }
  return(contador)
}

Nulos_rec(c(8,NA,NA,7,NA,NA,NA,8,7,1))
## [1] 5

Questão 10

No caderno escreva um pseudocódigo recursivo para o algoritmo que recebe como entrada um array qualquer e retorna outro array definido pela ordem inversa do array de entrada.

Em seguida, no computador, implemente o pseudocódigo elaborado.

Inverso_rec = function(v){
  if(!is.numeric(v))
    stop("o argumento de entrada tem que ser um vetor numérico.")
  
  n = length(v)
  if(n <= 1){
    return(v)
  } 
  
  y = c(v[length(v)], Inverso_rec( v[-length(v)] ) )
  return ( y )
  
}

Inverso_rec( c(1,2,3,4,5,6) )
## [1] 6 5 4 3 2 1