OneCompiler

Atividade 1

from typing import List
from functools import lru_cache


class MathOperations:
    """Uma classe contendo várias operações e algoritmos matemáticos."""

    @staticmethod
    def validate_positive_integer(n: int, operation_name: str) -> None:
        """Valida se um número é um inteiro positivo."""
        if not isinstance(n, int) or n < 0:
            raise ValueError(f"{operation_name} requer um número inteiro positivo.")

    @staticmethod
    def factorial(n: int) -> int:
        """Calcula o fatorial de um número recursivamente.
        
        Args:
            n: Um número inteiro positivo
        Returns:
            O fatorial de n
        """
        MathOperations.validate_positive_integer(n, "Fatorial")
        return 1 if n <= 1 else n * MathOperations.factorial(n - 1)

    @staticmethod
    @lru_cache(maxsize=None)
    def fibonacci(n: int) -> int:
        """Calcula o n-ésimo número de Fibonacci usando memoização.
        
        Args:
            n: Um número inteiro positivo
        Returns:
            O n-ésimo número de Fibonacci
        """
        MathOperations.validate_positive_integer(n, "Fibonacci")
        if n <= 2:
            return 1
        return MathOperations.fibonacci(n - 1) + MathOperations.fibonacci(n - 2)

    @staticmethod
    def print_natural_numbers(limit: int, current: int = 1) -> None:
        """Imprime números naturais de current até limit recursivamente.
        
        Args:
            limit: O limite superior
            current: O número atual (padrão=1)
        """
        MathOperations.validate_positive_integer(limit, "Números naturais")
        if current > limit:
            return
        print(current)
        MathOperations.print_natural_numbers(limit, current + 1)

    @staticmethod
    def sum_recursive(n: int) -> int:
        """Calcula a soma dos números de 1 até n recursivamente.
        
        Args:
            n: Um número inteiro positivo
        Returns:
            A soma dos números de 1 até n
        """
        MathOperations.validate_positive_integer(n, "Soma")
        return 0 if n == 0 else n + MathOperations.sum_recursive(n - 1)

    @staticmethod
    def gcd(a: int, b: int) -> int:
        """Calcula o Máximo Divisor Comum usando o algoritmo de Euclides.
        
        Args:
            a: Primeiro número inteiro
            b: Segundo número inteiro
        Returns:
            O MDC de a e b
        """
        while b:
            a, b = b, a % b
        return abs(a)

    @staticmethod
    def lcm(a: int, b: int) -> int:
        """Calcula o Mínimo Múltiplo Comum usando o MDC.
        
        Args:
            a: Primeiro número inteiro
            b: Segundo número inteiro
        Returns:
            O MMC de a e b
        """
        return abs(a * b) // MathOperations.gcd(a, b) if a and b else 0

    @staticmethod
    def modular_addition_table(n: int) -> List[List[int]]:
        """Gera uma tabela de adição modular para Z_n.
        
        Args:
            n: Tamanho da tabela
        Returns:
            Lista 2D representando a tabela de adição modular
        """
        MathOperations.validate_positive_integer(n, "Adição modular")
        return [[((i + j) % n) for j in range(n)] for i in range(n)]

    @staticmethod
    def modular_multiplication_table(n: int) -> List[List[int]]:
        """Gera uma tabela de multiplicação modular para Z_n.
        
        Args:
            n: Tamanho da tabela
        Returns:
            Lista 2D representando a tabela de multiplicação modular
        """
        MathOperations.validate_positive_integer(n, "Multiplicação modular")
        return [[((i * j) % n) for j in range(n)] for i in range(n)]


def print_table(table: List[List[int]]) -> None:
    """Imprime uma tabela 2D com formatação adequada."""
    for row in table:
        print(' '.join(map(str, row)))


def main():
    """Função principal para demonstrar o uso da classe MathOperations."""
    math = MathOperations()

    try:
        # 1. Fatorial
        num = int(input("Digite um número inteiro positivo para fatorial: "))
        print(f"O fatorial de {num} é {math.factorial(num)}")

        # 2. Fibonacci
        n_terms = int(input("\nDigite o número de termos da sequência de Fibonacci: "))
        print(f"Sequência de Fibonacci até o {n_terms}º termo:")
        print(" ".join(str(math.fibonacci(i)) for i in range(1, n_terms + 1)))

        # 3. Números naturais
        limit = int(input("\nDigite um número natural para impressão: "))
        print("Números naturais:")
        math.print_natural_numbers(limit)

        # 4. Soma recursiva
        value = int(input("\nDigite um número para soma recursiva: "))
        print(f"A soma dos números de 1 até {value} é {math.sum_recursive(value)}")

        # 5. MDC e MMC
        a = int(input("\nNúmero A para MDC/MMC: "))
        b = int(input("Número B para MDC/MMC: "))
        print(f"O MDC de {a} e {b} é {math.gcd(a, b)}")
        print(f"O MMC de {a} e {b} é {math.lcm(a, b)}")

        # 6. Tabelas modulares
        n = int(input("\nDigite o tamanho das tabelas modulares: "))
        print("\nTabela de adição modular:")
        print_table(math.modular_addition_table(n))
        print("\nTabela de multiplicação modular:")
        print_table(math.modular_multiplication_table(n))

    except ValueError as e:
        print(f"Erro: {e}")
    except Exception as e:
        print(f"Ocorreu um erro inesperado: {e}")


if __name__ == "__main__":
    main()