Implementación de algoritmos de teoría de números/Números perfectos

De Wikilibros, la colección de libros de texto de contenido libre.

Descripción[editar]

Un número perfecto es un número natural que es igual a la suma de sus divisores propios positivos, sin incluirse él mismo. Así, 6 es un número perfecto, porque sus divisores propios son 1, 2 y 3; y 6 = 1 + 2 + 3. Los siguientes números perfectos son 28, 496 y 8128.

Implementación en distintos lenguajes de programación[editar]

Lenguaje Visual Basic .Net[editar]

Module Module1
    'Numero perfecto
    Sub Main()
        Dim Resultado As Integer
        For index As Integer = 1 To 8200
            Resultado = Perfecto(index)
            Console.WriteLine(Resultado)
            'Comparo el numero con el total sumado
            If Resultado = index Then
                Console.WriteLine("El numero " & index & " es PERFECTO: " & Resultado)
            Else
                Console.WriteLine("El numero " & index & " no es perfecto: " & Resultado)
            End If
        Next
        Console.ReadKey()
    End Sub
    Function Perfecto(ByVal Numero As Integer) 'Averiguo si el numero es perfecto
        Dim Total As Integer
        For index As Integer = 1 To Numero - 1
            If Numero Mod index = 0 Then
                Total = Total + index
            End If
        Next
        Return Total
    End Function
End Module

Lenguaje C[editar]

El siguiente código permite determinar si un número es perfecto:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

int numeroPerfecto(int num);

int main()
{
    int numero;

    printf("\nIngrese un numero: ");
    scanf("%i", &numero);
                      
    if(numeroPerfecto(numero))
        printf("\nEs Perfecto\n");
    else
        printf("\nNo es Perfecto\n");
    getchar();
    return 0;
}

int numeroPerfecto(int num)
{
    int acum = 0;
    int i;
    
    for (i = 1; i <= (num / 2); i++) {
        if (num % i == 0) {
            acum += i;
        }
    }
    if (acum == num) {
        return 1;
    } else {
        return 0;
    }        
}

Otro ejemplo:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main ()
{
    int n, i, resto, suma;
    
    printf("\nEste programa comprueba si un numero entero es perfecto o no");
    printf("\n\nIntroduce el numero: "); 
    scanf("%i", &n);  
    suma = 0;
    resto = 0;
    for (i = 1; i <= (n / 2); i++)       //cuenta desde 1 hasta n/2 : El mayor múltiplo posible de n, asumiendo que n es divisible por 2, es n/2.
    {
       resto = n % i;
       if (resto==0) {       
          suma = suma + i;
       }
    }
    if (n == suma) {
       printf("\nEl numero %i es perfecto\n\n",n);
    } else {
       printf("\nEl numero %i no es perfecto\n\n",n);
    }
    return (0); 
}

Lenguaje PHP[editar]

<?php 
/* Este programa crea números perfectos en un rango dado. */
$inicio = 0; //número donde inica el rango
$fin = 1000; //número donde ternina el rango

for ($orsq=$inicio; $orsq<=$fin; $orsq++) //ciclo que nos sirve para recorer el rango deseado
   {
      $c=0; // contador para almacenar los datos con residuo con valor de cero
	for ($b=1; $b<$orsq; $b++) //ciclo for para efectuar la división desde el valor de inicio hasta el número de fin
        {
           $o=$orsq%$b; //operación para obtener el residuo si es Cero
           if ($o==0) //decisión si secumple
            {
             $c=$c+$b; //sumará al contador el valor de contador más el número que posee residuo cero
            }
        }
          if ($c==$orsq)//si el contador es igual al valor recorido en el primer ciclo entonses es un numero perfecto
            {
	 echo "$orsq es un numero perfecto<br />"; // visualizar el número perfecto
	 }
   }
?>

Otro ejemplo:

        <?php
            /* Funcion que al pasarle un numero nos imprime si es perfecto o no, nos regresa 1 en caso de ser perfecto y 
               0 en caso contrario.
               Autor: Eduardo Cortez*/

            function numeroPerfecto($numero){
                for($i=1;$i<$numero;$i++){
                    $residuo=$numero%$i;
                    if($residuo==0){
                        $sum=$i+$sum;
                    }
                }
                if($sum==$numero){
                    echo("El numero es perfecto");
                    return 1;
                }else{
                    echo("El numero no es perfecto");
                    return 0;
                }
            }
        ?>

LogoFE (Lenguaje Logo)[editar]

muestra divisores 16
[1 2 4 8 16]

muestra menosultimo divisores 16
[1 2 4 8]

muestra suma menosultimo divisores 16
15

muestra expon [[suma menosultimo divisores] mismo] 16
[15 16]

muestra serie frase [1 1] 16
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]

muestra escoge [esigual expon [[suma menosultimo divisores] mismo]] serie frase [1 1] 100
[1 6 28]

muestra escoge [esigual expon [[suma menosultimo divisores] mismo]] serie frase [1 1] 1000
[1 6 28 496]

funciona "perfectos.menores.que [escoge [esigual expon [[suma menosultimo divisores] mismo]] serie frase [1 1]]

muestra perfectos.menores.que 100
[1 6 28]

VisualBasic[editar]

Este código permite ver si un número es perfecto o no, aunque está limitado a los cinco primeros números perfectos ya que el sexto provoca un error de desbordamiento.

numero = Val(TextBox1.Text)
sumas = 0
For i = 1 To numero - 1
    If numero Mod i = 0 Then sumas = sumas + i
Next
If sumas = numero Then
    Label5.Text = Str(numero) + " es un numero perfecto"
Else
    Label5.Text = Str(numero) + " no es un numero perfecto"
End If

C#[editar]

El siguiente código en C# muestra la cantidad de números perfectos indicada por cant.

private static bool EsPerfecto(Int64 n)
{
    Int64 t = 0;
    for (Int64 i = 1; i < n; i++)
        if (n % i == 0) t += i;
    return (n == t);
}

private static void Lista(int cant)
{
    for (Int64 i = 1; cant > 0; i++)
    {
        if (EsPerfecto(i))
        {
            Console.WriteLine(i);
            cant--;
        }
    }
}

static void Main(string[] args)
{
    Lista(3);//Imprime los primeros 3
    Console.ReadLine();
}

F#[editar]

El siguiente código en F# permite comprobar si un número dado es perfecto o no.

open System

let divisores n = set [ for i in 1 .. float n |> sqrt |> int do if n % i = 0 then yield! [i; n / i] ]

let esPerfecto n = (divisores n |> Set.toList |> List.sum) - n = n

[<EntryPoint>]
let main argv =
    printf "Introduzca un número: "
    Console.ReadLine() |> Int32.Parse |> esPerfecto |> printfn "Es perfecto: %b"   

    0

Haskell[editar]

El siguiente código genera la lista de números perfectos.

listaperfec :: [Int]
listaperfec = [x | x <- [2..], perfecto x]
	 where perfecto n = sum (divisores n) == n 
	 			where divisores n = [x | x <- [1..(n-1)], n `mod` x == 0]




sum::[Int]->Int
sum [] = 0
sum (x:xs) = x+ (sum xs)

Otra Alternativa más Eficiente[editar]

{-
  Función para determinar si un número es primo
-}

esPrimo :: Integer -> Integer -> Bool
esPrimo _ 1 = True
esPrimo x n = ((mod x n) /= 0) && (esPrimo x (n - 1))

{-
	Función para dar la lista de los Números Perfectos
-}

perfectos :: [Integer]
perfectos = [x | x <- [2..], esPrimo (2^x-1) (2^x - 2) , x <- [(2^(x-1))*(2^x-1)]]

Java[editar]

Este código permite comprobar si un número dado es perfecto.

class perfecto {
    public static void main(String args[]) {
        int numero=6;
        int sumas=1, menor=2, Mayor=numero;
        while ( menor < Mayor ) {
            Mayor = numero / menor;
            if ( numero % menor == 0 ) 
                sumas += menor;
            if ( Mayor != menor && numero % Mayor == 0 )
                sumas += Mayor;
            
	}
        if (sumas == numero) {
            System.out.println("El numero "+numero+" es un numero perfecto;");
        } else {
            System.out.println("El numero "+numero+" no es un numero perfecto;");
        }
    }
}

Otra forma para el código

// Rey Salcedo
class perfecto {
    public static void main(String args[]) {
        int numero=6;
        int sumas=0;
        for(int i = 1;i < numero - 1;i++){
		if(numero % i == 0)
		    sumas += i;
		}
        if (sumas == numero) {
            System.out.println("El numero "+numero+" es un numero perfecto;");
        } else {
            System.out.println("El numero "+numero+" no es un numero perfecto;");
        }
    }
}

Python[editar]

def perfecto(num):
    contador = 0
    for i in range(1,num):
        if num % i == 0:
            contador += i
    if contador == num:
        print (u"Es un número perfecto.")
    else:
        print (u"No es un número perfecto.")
# llamando al método, probando con el número 6
perfecto(6)

SLE[editar]

Generador de números perfectos

variables

t,v,x,y,z,maxnum	:numerico

inicio
leer(maxnum)
cls()
v=2
desde x=6 hasta maxnum{
desde y=2 hasta x{				
si(x%y==0){
z=x/y
t=t+z}}
si(x==6){imprimir("1.- 1\n")}
si(t==x){imprimir(v,".- ",x,"\n"); v=v+1}
t=0}
imprimir("programa finalizado")
fin

Fortran 90[editar]

Este código permite ver si un número es perfecto o no, aunque está limitado a los cinco primeros números perfectos ya que el sexto provoca un error de desbordamiento.

program Perfecto
implicit none
integer ::num
Print*, "Dime un número"
Read*, num
If (perfect(num)) then
	Print*,"Es perfecto"
else
	Print*, "No es perfecto"
endif
pause
!!
Contains
	logical function perfect(n)
		Integer :: n,suma,i
		suma=0
		perfect=.false.
		Do i=1,n-1
			If (mod(n,i)==0) suma=suma+i
		enddo
		If (suma==n) perfect=.true.
	endfunction
endprogram

Scheme[editar]

Este código permite comprobar si un número dado es perfecto.

;funcion principal
(define (perfecto? A)
  (cond 
    ((= A 1) "No es Perfecto")
    ((= A (apply +(divisores A))) "Es perfecto")
    (else "No es Perfecto")
    )
  )
;funciones auxiliares
(define (divisores A)
  (cond
    ((= A 1) '(1))
    (else (cons 1 (divisores-aux A 2)))
    )
  )
(define (divisores-aux A B)
  (cond
    ((= A B) ())
    ((integer? (/ A B))(cons B (divisores-aux A (+ B 1))))
    (else (divisores-aux A (+ B 1)))
    )
  )

Batch Script[editar]

@echo off
:: Numeros perfectos, Leo Gutierrez R.
:code
set /p "numero=Numero : "
if not defined numero (goto:code)
set /a "i=1"
set /a "suma=0"
set /a "operacion=0"
:bucle
if %i% equ %numero% (goto:end)
set /a "operacion=%numero% %% %i%"
if %operacion% equ 0 (set /a "suma+=%i%")
set /a "i+=1"
goto:bucle
:end
if %suma% equ %numero% (
echo El numero es perfecto.
) else (
echo El numero no es perfecto.
)
goto:eof

Extended Pascal[editar]

Program NumerosPerfectos(input, output);
(*Este programa encuentra números perfectos.*)

Var
numero, divisor, acumulador : integer;

Begin
For numero:=1 To maxint Do
	Begin
		acumulador:=0; (*Este bucle calcula los divisores del número y los suma para realizar la comprobación.*)
		For divisor:=1 To numero-1 Do If (numero Mod divisor = 0) Then acumulador:=(acumulador + divisor);
		If (acumulador = numero) Then writeln(acumulador)
	End
End.

PSeInt (Estricto)[editar]

Proceso ITESA_LEVO
 Definir n, a, e, r, c Como Enteros;

 Escribir "----------Numero Perfecto----------";
 Escribir "Ingrese el numero:";
 Leer n;
 c<-1;
 a<-0;
    Repetir
	r<-n%c;
	Si r=0 Entonces
	Escribir c;
	a<-a+c;
	FinSi
	c<-c+1;
     Hasta Que c=n
     Si a=n Entonces
	Escribir "----";
	Escribir a;
	Escribir "El numero es perfecto!";
     Sino
     Escribir "----";
	Escribir a;
	Escribir "El numero no es perfecto!";
FinSi
FinProceso

Otra forma:

Proceso ITESA_LEVO_2
	Definir t,v,x,yy,z,maxnum Como Entero;
	t<-0;
	Leer maxnum;
	v<-2;
	Para x<-6 Hasta maxnum Con Paso 1 Hacer
		Para yy<-2 Hasta x Con Paso 1 Hacer		
			Si x%yy=0 Entonces
				z<-x/yy;
				t<-t+z;
			FinSi
		FinPara
		Si x=6 Entonces 
			Escribir "1.- 1";
		FinSi
		Si t=x Entonces 
			Escribir v,".- ",x; v<-v+1;
			t<-0;
		FinSi
	FinPara
	Escribir "programa finalizado";
FinProceso