Implementación de algoritmos de teoría de números/Números amigos
Apariencia
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]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;
}
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.
}
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;
}
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
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 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 )
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;
}
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