## Laboratorio 5 CC1002 Primavera 2024
## Profesor: J. Alvarez
## Auxiliares: Jean Paul Duchens, Valentina Alarcón, Teresa Peralta, Joaquín Salas


## Pregunta 1

## Funcion utilizada de primos.py
def esPrimo(n):
  assert type(n)==int and n>1
  if n%2==0:
      #numero par
      return n==2
  else:
      #numero impar
      def _esPrimo(n,divisor):
          if divisor*divisor > n: 
              return True
          elif n % divisor == 0: 
              return False
          else:
              return _esPrimo(n,divisor+2)
      return _esPrimo(n,3)

def siguientePrimo(n):
    assert type(n)==int and n>1
    if n%2==0:
        sgte=n+1
    else:
        sgte=n+2
    if esPrimo(sgte): 
        return sgte
    else:
        return siguientePrimo(sgte)

#sonGemelos: int int -> bool
#True si x e y son primos impares consecutivos
#ej: sonGemelos(5,7)->True, sonGemelos(13,17)->False
def sonGemelos(x, y):
    assert type(x) == int 
    assert type(y) == int
    assert x < y
    assert x > 0
    return (esPrimo(x) and esPrimo(y)) and ((x % 2 != 0) and (y % 2 != 0)) and (x + 2 == y)

assert sonGemelos(5,7) == True
assert sonGemelos(13,17) == False

#enRango: int int ->
#escribir gemelos en el rango entre x e y
#usando función sonGemelos
#ej: enRango(3,20) escribe 3 5, 5 7, 11 13, 17 19
def enRango(x, y):
    assert type(x) == int
    assert type(y) == int
    assert x < y
    assert x > 0

    if x >= y: 
        return
    if esPrimo(x) and sonGemelos(x, siguientePrimo(x)):
        print(x, siguientePrimo(x))
    enRango(siguientePrimo(x), y)

#enRango(3,20)

## Pregunta 2

def perfecto(x):
    assert type(x) == int
    assert x > 0
    def suma_divisores(x,y):
        if y == 0:
            return 0
        if (x % y) == 0:
            return y + suma_divisores(x, y-1)
        else:
            return suma_divisores(x, y-1)
    return (suma_divisores(x, x-1) == x)

assert perfecto(6) == True
assert perfecto(28) == True

def escribir_perfectos(x, y):
    assert type(x) == int
    assert type(y) == int
    assert x < y
    assert x > 0

    if x == y:
        return
    if perfecto(x):
        print(x)
    return escribir_perfectos(x+1, y)

#escribir_perfectos(1,100)