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

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 distintos lenguajes de programación

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;
}

Otra solución que implementa una solución diciendo si se cumple que un de número ingresado es amigo de otro número ingresado

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

int numeros_amigos(int x, int y)
{
    int suma_x=0;
    int suma_y=0;
    int i, k;
    for (i = 1; i < x; i++)
    {
        if (x%i==0)
            suma_x+=i;
    }
    for (k = 1; k < y; k++)
    {
        if (y%k==0)
            suma_y+=k;
    }
    return (suma_x==y && suma_y==x);
}

int main()
{
    int n_1, n_2;
    printf("Introduzca el nº 1: ");
    scanf("%d",&n_1);
    printf("Introduzca el nº 2: ");
    scanf("%d",&n_2);

    if (numeros_amigos(n_1,n_2))
        printf ("¡Son amigos! :)");
    else
        printf ("No son amigos :(");
    getch();
    return 0;
}

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.
}
#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;
}

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
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 más 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");
		}
			
	}
}

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>

PSeInt (Estricto)

editar
Proceso numeros_amigos
	//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
	
	Definir acum Como Entero;
	Definir a Como Entero;
	Definir b Como Entero;
	Definir cont Como Entero;
	Definir div_a Como Entero;
	Definir div_b Como Entero;
	
	a<-0;
	cont<-0;
	acum<-0;
	
	Escribir "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.";
	
	Mientras a==a Hacer 
		
		Escribir "Ingrese un nº: ";
		Leer a;
		Escribir "Ingrese otro nº: ";
		Leer b;
		Mientras cont<a-1 Hacer
			cont<-cont+1;
			Si a%cont=0 Entonces
				acum<-acum+cont;
			FinSi
		FinMientras
		
		div_a<-acum;
		cont<-0;
		acum<-0;
		
		Mientras cont<b-1 Hacer
			cont<-cont+1;
			Si b%cont=0 Entonces
				acum<-acum+cont;
			FinSi
		FinMientras
		
		div_b<-acum;
		
		Si (div_a==b y div_b==a) y a<>b Entonces
			Escribir "los nºs son amigos";
		Sino Si (div_a==b y div_b==a) y (a==b) Entonces
				Escribir "Los números son iguales y perfectos";
			Sino
				Escribir "los nºs no son amigos";
			FinSi
		FinSi
	FinMientras
FinProceso

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):
    suma_x=0
    suma_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
 
# Cuerpo del programa
n_1=int(input('Introduzca el nº 1: '))
n_2=int(input('Introduzca el nº 2: '))
 
if numeros_amigos(n_1,n_2):
    print ('¡Son amigos! :)')
else:
    print ('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 )
/*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
#!/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;
}

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):
    suma_x=0
    suma_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
 
# Cuerpo del programa
n_1=int(input('Introduzca el nº 1: '))
n_2=int(input('Introduzca el nº 2: '))
 
if numeros_amigos(n_1,n_2):
    print ('¡Son amigos! :)')
else:
    print ('No son amigos :(')

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