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

De Wikilibros, la colección de libros de texto de contenido libre.
Saltar a: navegación, buscar

Dos números amigos son dos enteros positivos a y b tales que a es la suma de los divisores propios de b, y b es la suma de los divisores propios de a. (la unidad se considera divisor propio, pero no lo es el mismo número).

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

JavaScript[editar]

Comprobar si dos números son amigos mediante JS.

<script>
function divisores(n) {
	var a=1;
	var b=0;
	var l = new Array();
	while(a<n) {
		var h = n % a;
		if(h == 0) {
			l[b]=a;
			b++;
		}
		a++;
	}
	return l;
}
 
function suma(L) {
	var lg=L.length;
	var a=0;
	var sum=0;
	while(a<lg) {
		sum=sum+L[a];
		a++;
	}
	return sum;
}
 
n1=prompt('Introduce el primer num.:');
n2=prompt('Introduce el segundo num.:');
L1=divisores(n1);
L2=divisores(n2);
s1=suma(L1);
s2=suma(L2);
 
if(s1==n2 && s2==n1) {
	alert('Los numeros son amigos');
} else {
	alert('Los numeros no son amigos');
}
</script>

Python[editar]

Comprobar si dos números son amigos.

#Para Python 3.2.2
 
# Definición de la función de comprobación de números amigos
def numeros_amigos(x,y):
    a_x=0
    a_y=0
 for i in range(1,x):
 if x%i==0:
    suma_x+=i
 for k in range(1,y):
    if y%k==0:
    suma_y+=k
return suma_x==y and suma_y==x
 
 
numero1=int(input('Introduzca el nº 1: '))
numero2=int(input('Introduzca el nº 2: '))
 
if numeros_amigos(numero1,numero2):
    print ('¡Son amigos! :)')
else:
    print ('No son amigos :(')

Haskell[editar]

--Definición de la función "sonNumerosAmigos x y"

sonNumerosAmigos :: Int -> Int -> Bool

sonNumerosAmigos x y = if (x > 0 && y > 0) then ( sum (listaDivisores y) == x && sum 
(listaDivisores x) == y ) else error("Los números deben ser enteros positivos")
       where listaDivisores n = [ x | x <- [1..(n-1)], (mod n x) == 0]

--Otro algoritmo un poco más completo:


--Devuelve una lista con los divisores entre n y m
divisores :: Int -> Int -> [Int]
divisores n 1 = [1]
divisores n m = if mod n m == 0 then (m):divisores n (m-1) else divisores n (m-1)

-- Devuelve la lista de divisores de n
divisoresN :: Int -> [Int]
divisoresN n = divisores n n

-- Funcion que devuelve la suma de los elementos de una lista.
sumaList :: [Int] -> Int
sumaList [] =0
sumaList (x:xs) = x+sumaList(xs)

--Funcion que determina si dos numeros son amigos
amigos :: Int -> Int -> Bool
amigos a b = (sumaList(divisoresN a)-a)== b && (sumaList(divisoresN b)-b) == a

VB .NET[editar]

    Private Function numeros_amigos(ByVal num_1 As Integer, ByVal num_2 As Integer) As Boolean
        Dim x As Integer            'Contador para bucles num_1 y num_2
        Dim suma_1 As Integer       'Acumular de suma de divisibles de Num_1
        Dim suma_2 As Integer       'Acumular de suma de divisibles de Num_2
 
        x = 1       'Inicializamos a 0 el bucle para sacar los números divisibles de num_1
 
        Do
            If num_1 Mod x = 0 Then     ' Si la division es 0 entra
                suma_1 = suma_1 + x     'Guardamos la suma de los divisibles para luego comparala
            End If
            x = x + 1
        Loop Until x >= num_1           'Recorre todos los números hasta ser + o = a num_1
 
        x = 1       'Inicializamos a 0 el bucle para sacar los números divisibles de num_2
 
        Do
            If num_2 Mod x = 0 Then     ' Si la division es 0 entra
                suma_2 = suma_2 + x     'Guardamos la suma de los divisibles para luego comparala
            End If
            x = x + 1
        Loop Until x >= num_2           'Recorre todos los números hasta ser + o = a num_2
 
        If ((suma_1 = num_2) And (suma_2 = num_1)) Then 'Si la suma de los divisibles de num_1 es
                                                        '= a num_2 o al reves entra
            numeros_amigos = True
        Else
            numeros_amigos = False
        End If
 
    End Function
 
    Sub main()
        Dim num_1 As Integer
        Dim num_2 As Integer
 
        Console.Write("Introduzca el primer numero:  ")
        num_1 = CInt(Console.ReadLine())
        Console.Write("Introduzca el segundo numero: ")
        num_2 = CInt(Console.ReadLine())
        Console.WriteLine("")
 
       Console.Write("La comparación para saber si los números {0} y {1}", num_1, num_2)
       Console.Write("son amigos es: {0}", numeros_amigos(num_1, num_2))
       Console.ReadLine()
    End Sub

C[editar]

#include    <stdlib.h>
#include    <stdio.h>
 
#define MAXIMO 10000
 
int sumadivisores(int);
 
int main ()
{
    int control=0, suma1, suma2;
    for ( int i=0; i<MAXIMO;i++ ){
        suma1 = sumadivisores(i);
        suma2 = sumadivisores(suma1);
        if ((suma2==i) && (i!=suma1) )
        {
            if (suma2!=control) printf ( "%d - %d\n", i, suma1 );
            control=suma1;
        }
    }
    return EXIT_SUCCESS;
}
 
int sumadivisores(int a)
{
    int sumador=0;
    for ( int i=1; i <=a/2 ; i++ ) if ((a % i)==0) sumador += i;
    return sumador;
}

C++ Paralelizado[editar]

/* Iker Ruiz Arnauda ITESO */
 
#include "stdio.h"
#include "time.h"
#include "windows.h"
//#include "advisor-annotate.h" Libreria para las anotaciones del parallel
 
//Variables Globales.
 
int inicial,final;   //Variables globales ingresadas por usuario.
int nThreads;		 //Número de Hilos a utilizar
clock_t t_ini,t_fin; //Cronometro.
 
//Fin Variables Globales.
 
 
//Función Sumafacts (Recibe un valor de tipo INT)
int sumafacts(int n)
{
//Variables Locales sumafacts.
int i;
int suma=0;
int factor;
//Fin Variables Locales sumafacts.
 
for(i=n;i>1;i--)
if(n%i==0)
{
		factor=n/i;
		suma+=factor;
}
return(suma);
}
 
DWORD WINAPI ProductoAmigos(LPVOID arg)
{
	int nhilo=*((int *)arg);
	int i,j;
	t_ini=clock();
 
	//ANNOTATE_SITE_BEGIN(solve);
 
	for(i=nhilo;i<final;i+=nThreads) //Dependiendo los hilos se va a dividir el trabajo, Ej.(1,3,5,7 Core0, 2,4,6,8 Core1)
    {
		j=sumafacts(i); //El valor de J es determinado por la función sumafacts pasandole el valor del contador i.
        if(sumafacts(j)==i && i!=j) //Si el valor de sumafacts(j) es igual al contador i e i es diferente del valor de J:
        printf("%d y %d son numeros amigos\n",i,j);
    }
 
	//ANNOTATE_SITE_END(solve);
	return 0;
}
 
int main()
{
int i; //Contador para crear los Hilos
 
printf("Numero de Hilos que quieres crear: "); //Número de Hilos
scanf("%d", &nThreads);
if(nThreads > 64) nThreads = 64;
 
printf("Introduce el Valor Inicial: "); //Valor inferior del rango
scanf("%d",&inicial);
 
printf("Introduce el Valor Final: "); //Valor superior del rango
scanf("%d",&final);
printf("\n");
 
HANDLE *pThreadHandles = new HANDLE[nThreads]; //Se crea el arreglo de acuerdo a lo que se leyo en la variable nThreads (Numero de Hilos).
int *pThreadParameters = new int[nThreads]; //Se crea el arreglo pasandole tambíen el parametro del número de Hilos
 
for (i = 0; i < nThreads; i++) //Ciclo para crear los hilos.
{
    pThreadParameters[i] = i;
    pThreadHandles[i] = CreateThread(NULL,0,ProductoAmigos, &pThreadParameters[i],0,NULL);
}
 
WaitForMultipleObjects(nThreads, pThreadHandles, TRUE, INFINITE); //Espera a que terminen los hilos.
delete [] pThreadParameters;
delete [] pThreadHandles;
 
t_fin=clock(); //Termina el cronometro.
printf("\nTiempo %3.6f segundos\n",((float) t_fin- (float)t_ini)/ CLOCKS_PER_SEC); //Tiempo de la operación.
Sleep ( 8000 ); //Espera para que se aprecien los resultados.
}

C++[editar]

#include <iostream>
 
int main()
{
  long n1, n2, acum1, acum2, N, i;
 
  cout << "Introduce el maximo: ";
  cin >> N;
 
    for (n1=2; n1<N; n1= n1+1)
    {  for (n2= n1+ 1; n2<= N; n2= n2+1)
       {  acum1= 0; acum2= 0;
          for (i= 1; i<=n1/2; i= i+1)
          {  if (n1%i== 0)
                acum1= acum1+i;
          }
          for (i= 1; i<=n2/2; i= i+1)
          {  if (n2%i== 0)
                acum2= acum2+i;
          }
          if (n1== acum2 && n2== acum1)
             cout << n1 << " " << n2 << endl;
       }
    }
 
cout << endl << "No se encontaron mas amigos";
 
getch();
return 0;
}

Java[editar]

despliega "n" primeros números amigos
made by zero
public class Nlist
	{
 
	public static int cont=0;
	public static void main(String[] args) throws Exception
	{
 
			for(int i=2;i<n+2;i++)
			{
				System.out.print(i-1+ " ");
				pop(i);
 
 
			}
	System.in.read();
 
	}
 
	public static void pop(int num)
	{
 
		int p=3*((int)Math.pow(2,num-1))-1;
		int q=(3*((int)Math.pow(2,num)))-1;
		int r=9*(int)Math.pow(2,2*num-1)-1;
		int num1=(int)Math.pow(2,num)*p*q;
		int num2=(int)Math.pow(2,num)*r;
		System.out.println("num1 "+num1 +" num2 "+num2);
 
 
 
	}
 
	}
 
 
//APLICACIÓN QUE VERIFICA SI DOS NÚMEROS SON AMIGOS
 
import javax.swing.JOptionPane;
public class Main {
public static void main(String[] args) {
 
    String Cade1, Cade2;
    int num1, num2, i, div1, div2;
    i = 1;
    div1 = 0;
    div2 = 0;
 
    Cade1=JOptionPane.showInputDialog("Ingrese primer numero");
    num1=Integer.parseInt(Cade1);
    Cade2=JOptionPane.showInputDialog("Ingrese primer numero");
    num2=Integer.parseInt(Cade2);
 
 
     while(i < num1){ // Mientras 'i' sea menor o igual a 'numero1'
            if(num1%i == 0){ // Si 'numero1'%'i' es igual a   
               div1 = div1 + i; // suma los divisores de numero 1     
            }
            i++;
     }
        i=1;
     while(i < num2){ // Mientras 'i' sea menor 'numero2'
         if(num2%i == 0){ // Si 'numero1'%'i' es igual a
            div2 = div2 + i; // suma los divisores de numero 2
         }
         i++;
     }
     if (div1 == num2 & div2 == num1){
         JOptionPane.showMessageDialog( null, "LOS NUMEROS SON AMIGOS", "Resultado", JOptionPane.INFORMATION_MESSAGE );
 
        }
     else {
         JOptionPane.showMessageDialog(null,"NO SON NUMEROS AMIGOS","Resultado",0);
     }
 
 
     }
}

DE UNA MANERA SENCILLA

public class amigos {
  public static void main(String[] args) {
    int n,m,j,cont,conta,i;
    boolean sec,ff;
    sec=false;
    ff=false;
    conta=0;
    cont=0;
    do{
      StdOut.println("ingrese dos numeros");
    n=StdIn.readInt();
    m=StdIn.readInt();
    }while ((n<=0)||(m<=0));
    for(i=1; i<n; i++){
      if(n%i==0)
      cont=cont+i;
      if (cont==m)
        ff=true;
 
    }
    for(j=1; j<m; j++)
      if(m%j==0){
      conta=conta+j;
      if (conta==n)
        sec=true;
 
    }
    if(ff&&sec)
      StdOut.println("Los numeros "+n+" y "+m+" son amigos");
    else
      StdOut.println("Los numeros "+n+" y "+m+" no son amigos");
  }
}

Otra manera mas y estructurada. Te permite saber si dos números son amigos.

//Autor: Rey Salcedo
public class NumerosAmigos{
	public static long sumaDivisores(long numero){
		long retornado = 0;
		for(long i = 1;i < numero-1;i++){
			if(numero % i == 0){
				retornado += i;
			}
		}
		return retornado;
	}
	public static boolean operacion(long n1, long n2){
		boolean retornado = false;
		if(sumaDivisores(n1) == n2 && sumaDivisores(n2) == n1){
			retornado = true;
		}
		return retornado;			
	}
	public static void main(String []args){
		long numero1 = 1184;
		long numero2 = 1210;
		if(operacion(numero1, numero2)){
			System.out.println("Los numero "+ numero1 + " y "+ numero2+" son amigos");
		}else{
			System.out.println("Los numero "+ numero1 + " y "+ numero2+" no son amigos");
		}
 
	}
}

Scheme[editar]

;funcion principal
(define (amigos? A B)
  (cond
    ((and (= A (sumdivisores B 1)) (= B (sumdivisores A 1)))"Amigos")
    (else "No Amigos")
    )
  )
;funcion secundaria:suma los divisores de cada numero
(define (sumdivisores A B)
 (cond
   ((= A B) 0)
   ((integer? (/ A B))(+ B (sumdivisores A (+ B 1))))
   (else (sumdivisores A (+ B 1)))
   )
  prawn )

SLE[editar]

/*Este algoritmo calcula si dos números ingresados por el usuario son amigos. En el caso de ser iguales 
y la suma de sus divisores también, advierte que son perfectos. Puede ser modificado fácilmente para que
automáticamente busque los números él mismo*/
 
var
acum : numerico
a : numerico
b : numerico
cont : numerico
div_a : numerico
div_b : numerico
 
inicio
 
imprimir ("\nDos números amigos son dos enteros positivos a y b", 
          "\ntales que a es la suma de los divisores propios de", 
          "\nb y b es la suma de los divisores propios de a.")
 
mientras (a==a){
 
imprimir ("\nIngrese un nº: ")
leer (a)
imprimir ("\ningrese otro nº: ")
leer (b)
 mientras (cont <a-1){
 cont=cont+1
   si (a%cont==0){
    acum=acum+cont
   }
 }
div_a=acum
cont=0
acum=0
 
 mientras (cont<b-1){
  cont=cont+1
    si (b%cont==0){
     acum=acum+cont
    }
}
div_b=acum
 
si ((div_a==b and div_b==a) and (a<>b)){
  imprimir ("\nlos nºs son amigos")
sino si ((div_a==b and div_b==a) and (a==b))
  imprimir ("\nLos números son iguales y perfectos")
sino
  imprimir ("\nlos nºs no son amigos")
}
fin

PERL[editar]

#!/usr/bin/perl
 
# encuentra numeros amigos hasta un número determinado 
# por el usuario, que en este script es $limitnumber = 333333344444;
# 
# autor: Juan Carlos Morataya Ramos
# fecha: 26 de enero de 2012.
# 
 
use strict;
use warnings;
 
my $limitnumber = 333333344444;
my $nfrd = 0;
my $h;
 
# programa principal
for ($h = 2; $h < $limitnumber; $h++) {
	if ($h == $nfrd) { next }
	my $numval = checksum($h);
	my $friend = checksum($numval);
	if ($friend) {
		if ($h != $numval) {
			if ($h == $friend) {
				print "$numval y $h son numeros amigos!\n";
				$nfrd = $numval;
			}
	    }
    }
}
 
# funcion para encontrar numeros divisibles
sub checksum {
	my $i;
	my $test;
	my $sum;
	my $mynum = $_[0];
	for ($i = 1; $i < $mynum; $i++) {
		$test = $mynum % $i;
		# encuentra numeros multiplos
		if ($test == 0) {
			$sum += $i;
		}
	}	
	return $sum;
}