Aula Prática 3 - Invocação, Recursividade e Input/Output

O objetivo desta aula é experimentar a definição de funções que invocam outras funções, bem como a definição de funções recursivas. Esta aula tem também dois objetivos adicionais: experimentar a definição de procedimentos e o desenvolvimento de código com input e output com o utilizador. Após a realização da prática, deverá ter sido adquirida uma noção básica dos seguintes conceitos:

  • Invocação de função
  • Invocação recursiva de função
  • Utilização de variáveis e estruturas de controlo para efetuar:
    • Iterações
    • Acumulações
    • Contagens
    • Pesquisas
  • Utilização de input e output

Invocação e Recursividade

Trabalho prévio

Desenvolva um módulo com funções que permitam:

1. Obter o número de divisores de um número inteiro n.

Esta função deverá iterar sobre os números naturais até n, contando os números que são divisores de n. Exemplo:

    number_of_divisors(8) → 4     (1, 2, 4, 8)
In [ ]:
 

2. Obter o somatório dos divisores próprios de um número inteiro n

Note que o conjunto dos divisores próprios exclui o próprio número.

Esta função deverá iterar sobre os números naturais até n (exclusive), acumulando os números que são divisores de n.
Exemplo:

    sum_of_divisors(6) → 6     (1 + 2 + 3)
In [ ]:
 

Exercícios

1. Defina uma função que recebe como argumento um número natural n e devolve verdadeiro caso n seja primo, ou falso caso contrário.

Exemplo:

    is_prime(6) → false

Nota: nesta função é útil invocar a função do exercício 1 do trabalho prévio, que calcula quantos divisores tem um número. A função pode ser invocada da seguinte forma:

    n = number_of_divisors(8)

Após a instrução executar, a variável n tomará o valor devolvido pela invocação da função number_of_divisors().

In [ ]:
 

2. Defina uma função que recebe como argumento um número natural n e devolve o somatório dos números primos menores que n.

Exemplo:

    sum_of_primes_smaller_than(8) → 17      (2 + 3 + 5 + 7)
In [ ]:
 

3. Defina uma função que recebe como argumento um número natural n e devolve o número de primos até n (inclusive).

Exemplo:

    number_of_primes_up_to(11) → 5       (2, 3, 5, 7, 11)
In [ ]:
 

4. Defina funções recursivas para calcular:

(a) o n-ésimo número de Fibonacci.

Exemplo:

    fibonacci(6) → 8
In [ ]:
 
(b) o fatorial de um número.

Exemplo:

    factorial(5) → 120
In [ ]:
 
(c) o máximo divisor comum entre dois números.

Exemplo:

    gcd(30, 25) → 5
In [ ]:
 

Procedimentos e Input/Output

Trabalho prévio

Desenvolva um módulo com funções e procedimentos que permitam:

1. Obter um número inteiro entre m e n introduzido pelo utilizador.

Esta função deverá pedir ao utilizador para introduzir um número inteiro entre os limites dados. Caso o utilizador introduza um número inteiro fora desse intervalo, a função voltar a pedir ao utilizador para introduzir um número inteiro dentros dos limites dados. Exemplo:

    value_between(1, 6) → 2 (o utilizador introduziu o valor 2)
In [ ]:
 

2. Escrever no ecrã os número inteiros entre m e n (inclusive), por ordem crescente.

Este procedimento deverá escrever no ecrã por ordem crescente todos os números inteiros entre os limites dados na invocação do procedimento. Exemplo:

    print_ascending_between(1, 5)
    1
    2
    3
    4
    5
In [ ]:
 

Exercícios

1. Defina um procedimento que dado um número inteiro entre 1 e 9 o escreva em numeração romana.

Exemplo:

    print_units_in_roman(6)
    VI
In [ ]:
 

2. Defina um procedimento que dado um número inteiro entre 1 e 9 o escreva em numeração romana considerando que este representa dezenas.

    print_tens_in_roman(6)
    LX
In [ ]:
 

3. Defina um procedimento que, usando os dois anteriores, dado um número inteiro entre 1 e 99 o escreva em numeração romana.

Exemplo:

    print_in_roman(66)
    LXVI
In [ ]:
 

4. Defina dois procedimentos que escrevem no ecrã os número inteiros entre m e n, por ordem decrescente. Um deve incluir os limites e o outro não deve incluir os limites.

In [ ]:
 

5. Defina dois procedimentos que escrevem no ecrã os número inteiros entre m e n (inclusive em m e exclusive em n) de h em h. Um procedimento deve fazê-lo por ordem crescente e o outro por ordem decrescente.

Exemplo:

    print_ascending_between_in_h(6, 18, 3)
    6
    9
    12
    15
In [ ]:
 

6. Defina uma função que pede ao utilizador números inteiros até ser introduzido o número zero e devolve verdadeiro se os números foram introduzidos por ordem crescente.

In [ ]:
 

7. Defina uma função que pede ao utilizador números inteiros até ser introduzido o número zero e devolve o número de números impares introduzidos.

In [ ]:
 

Exercícios extra

1. Analogamente ao exercício 1, defina uma função que permita saber se um número é perfeito.

Um número perfeito é tal que a soma dos seus divisores próprios é igual ao próprio número. Por exemplo, 6 é um número perfeito, dado que os seus divisores próprios são {3, 2, 1} e 3 + 2 + 1 = 6.

In [ ]:
 

2. Fazendo uso da alínea anterior, defina uma função que recebe como argumento um número natural n e que devolve o número de números perfeitos até n (inclusive).

Exemplo:

    number_of_perfect_numbers_up_to(30) → 2        (6, 28)
In [ ]:
 

3. Defina uma função que permite saber se existe algum número primo num dado intervalo (aberto).

Exemplo:

    exists_prime_between(5, 9) → true     (7 está no intervalo ]5, 9[)
In [ ]:
 

4. Defina uma função que recebe como argumento um número natural n e devolve a maior diferença entre dois números primos consecutivos até n.

Exemplo:

    larger_difference_between_primes(13) → 4     (a diferença entre 7 e 11)
In [ ]:
 

5. Defina uma função que pede ao utilizador números inteiros até ser introduzido o número zero e devolve o maior dos números introduzidos.

In [ ]: