Foro de elhacker.net

Programación => Programación General => Mensaje iniciado por: Charderak en 25 Junio 2010, 19:50 pm



Título: Programa para hallar números amigos
Publicado por: Charderak en 25 Junio 2010, 19:50 pm
Hola, tengo un problemilla haciendo este programa, tengo ya el código y no me da problemas al compilar, pero a la hora de ejecutarlo no hace nada, y no sé dónde puede estar el fallo. Os dejo el enunciado de la práctica para que entendáis qué estoy haciendo y el código, muchas gracias!

Enunciado:

Dos números a y b se dicen que son amigos si la suma de los divisores de a (salvo él mismo)
coincide con b y viceversa.
El menor par de números amigos es el formado por el 220 y el 284, ya que:
Suma de divisores de 220 (excepto 220): 1+2+4+5+10+11+20+22+44+55+110=284.
Suma de divisores de 284 (excepto 284): 1+2+4+71+142=220.
Otros números amigos son 2620 y 2924, 6232 y 6368, 17296 y 18416, 9363584 y 9437056.
Escribe un programa que tenga como entrada dos números naturales n y m y muestre en
pantalla todas las parejas de números naturales que existan en el intervalo [n, m].

Código:

   
Código
  1. PROGRAM PRACTICA4
  2. INTEGER a, b, i, j, n, m, s, t
  3. PRINT *, 'Introduzca el número n (el menor)'
  4. READ *, n
  5. PRINT *, 'Introduzca el número m (el mayor)'
  6. READ *, m
  7. DO WHILE (n<m)
  8. DO i=1, n/2
  9. a=MOD(n,i)
  10. IF (a==0) THEN
  11. s=s+i
  12. END IF
  13. END DO
  14. DO j=1, m/2
  15. b=MOD(m,j)
  16. IF (b==0) THEN
  17. t=t+j
  18. END IF
  19. END DO
  20. IF (s==t) THEN
  21. PRINT *, n, ' y ', m, ' son amigos'
  22. END IF
  23.                n=n+1
  24. END DO
  25. END


Título: Re: Programa para hallar números amigos
Publicado por: Debci en 25 Junio 2010, 20:59 pm
Primero no has dicho ni que lenguaje es ni nada por ele stilo, segundo ni has enmarcado el codigo ni que sea con quotes.

Usa geshi que por algo esta, y me comprometo a ayudarte.

Saludos


Título: Re: Programa para hallar números amigos
Publicado por: Charderak en 26 Junio 2010, 04:10 am
El lenguaje es Fortran, en cuanto a lo del "geshi" lo siento, pero no sé lo que es, lo he agrupado en colorines, en azul marino el ciclo DO WHILE principal, y en verde y negro los ciclos DO internos dentro del ciclo DO WHILE

Las instrucciones las he puesto en rojo


Título: Re: Programa para hallar números amigos
Publicado por: .:WindHack:. en 26 Junio 2010, 04:31 am
El lenguaje es Fortran, en cuanto a lo del "geshi" lo siento, pero no sé lo que es, lo he agrupado en colorines, en azul marino el ciclo DO WHILE principal, y en verde y negro los ciclos DO internos dentro del ciclo DO WHILE

Las instrucciones las he puesto en rojo

Se refiere a usar las etiquetas de código:

[code=fortran]/* Aquí el código del programa... */[/code]


Título: Re: Programa para hallar números amigos
Publicado por: Charderak en 26 Junio 2010, 17:57 pm
Listo, muchas gracias y a ver si así se anima alguien a echarme una mano :P


Título: Re: Programa para hallar números amigos
Publicado por: cbug en 26 Junio 2010, 18:16 pm
La verdad no conozco fortran, Pero lo que veo que puede traer fallas es que a s y t no los inicializaste. Ahora bien, no te deja ni siquiera leer los datos desde stdin?


Título: Re: Programa para hallar números amigos
Publicado por: Charderak en 26 Junio 2010, 19:07 pm
No es eso, en Fortran no hace falta inicializar las variables. Lo de stdin la verdad es que no entiendo a qué te refieres, pero el programa arrancar arranca y me pide los valores de n y m, pero al introducirlos ya no hace nada más


Título: Re: Programa para hallar números amigos
Publicado por: cbug en 27 Junio 2010, 04:59 am
En realidad ahora que lo miro con detenimiento:

Código:
DO WHILE (n<m)

En el rango del bucle, nunca modificas esos valores, no será más precisamente un

Código:
if(n<m)

 :huh:


Título: Re: Programa para hallar números amigos
Publicado por: Charderak en 27 Junio 2010, 05:21 am
En realidad ahora que lo miro con detenimiento:

Código:
DO WHILE (n<m)

En el rango del bucle, nunca modificas esos valores, no será más precisamente un

Código:
if(n<m)

 :huh:

Llevas razón, lo he corregido añadiendo un n=n+1 antes de cerrar el ciclo DO WHILE. Ahora sí "termina" de ejecutarse, pero no me aparece nada, sólo me pide los números y ya me sale lo de Press any key to continue, y estoy poniendo un intervalo donde sé seguro que hay al menos dos números "amigos", así que hay algo que está mal :(


Título: Re: Programa para hallar números amigos
Publicado por: cbug en 27 Junio 2010, 14:38 pm
En realidad ahora que leo el problema, el bucle sería:

Código:
do(n <= m)

Ya que es un intervalo cerrado.

Ahora bien, en el rango del bucle, la lógica está bien. Depuralo.

Por otra parte te recomienda que al problema le falto algo, recuerda esto : "programa que muestre TODAS las parejas".


Título: Re: Programa para hallar números amigos
Publicado por: Debci en 27 Junio 2010, 16:40 pm
Fijate que nunca s y t llegan a ser iguales por eso no lanza el print.

Hay un error de planteamiento del algoritmo.

Depuralo con algun debugger y verás que nunca se cumple la condicion.

Saludos


Título: Re: Programa para hallar números amigos
Publicado por: Charderak en 27 Junio 2010, 18:56 pm
Agradezco la ayuda, pero intentad ser un poco más concretos por favor, ya sé que hay un error en el algoritmo, por eso precisamente he creado el post.

En cuanto al depurador, no sé utilizarlo

Debci por qué dices que s y t nunca llegan a ser iguales? Si lo que hago es sumar los divisores de ambos números por separado y en caso de que la suma sea igual que me diga lo de que son "amigos"


Título: Re: Programa para hallar números amigos
Publicado por: ghastlyX en 27 Junio 2010, 19:10 pm
Bueno, ante todo no conozco Fortran ni lo he usado nunca, pero en tu código, no tendrías que poner a 0 las variables s y t para cada nuevo valor de n?

Otra cosa, por lo que veo, tú quieres encontrar los números amigos en un intervalo [n,m] y en tu código lo que haces es iterar sobre el valor de n y lo comparas con m, que la dejas fija. Así, suponiendo que lo que te he dicho arriba esté bien, sólo miras si m es amigo de algún número dentro del intervalo, pero si el intervalo es [30,50], no miras nunca si 34 es amigo de 42, por poner un ejemplo.

Una forma de corregir el algoritmo sería hacer lo siguiente (te lo pongo en pseudocódigo):
Código:
i := n;
mientras i <= m
    s := suma_divisores(i);
    si s > i y s <= m
        t := suma_divisores(s);
        si t = i
            imprime i " y " s " son amigos";
        fsi
    fsi
    i := i + 1;
fsi
Con este algoritmo, la complejidad es del orden de O(n2) puesto que tal y como tú calculas los divisores necesitas otro bucle lineal para cada número. En C++, el código quedaría así más o menos (no lo he probado):
Código
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. int suma_div(int n) {
  5.    int s = 0;
  6.    for (int i = 1; i <= n/2; ++i) if (n%i == 0) s += i;
  7.    return s;
  8. }
  9.  
  10. int main() {
  11.    int n, m;
  12.    cin >> n >> m;
  13.    for (int i = n; i <= m; ++i) {
  14.        int s = suma_div(i);
  15.        if (s > i and s <= m and suma_div(s) == i) cout << i << " y " << s << " son amigos" << endl;
  16.    }
  17. }
Para mejorar la eficiencia, podrías hacer una Criba de Eratóstenes al inicio del código para calcular todos los primos hasta la raíz cuadrada de m y luego para calcular los divisores, factorizar con dichos primos el número y generar con un pequeño bactracking todos los divisores, pero aunque supongo que iría más rápido, el código sería un poco más largo.


Título: Re: Programa para hallar números amigos
Publicado por: cbug en 27 Junio 2010, 19:17 pm
ghastlyX, creo que la programación funcional no es algo que tenga muy bien entendido él. Con lo de la inicialización según dijo, en fortran no se necesita  :xD.

Ahora bien, el error que le marcaba para revisar es lo que se citó:

Citar
sólo miras si m es amigo de algún número dentro del intervalo, pero si el intervalo es [30,50], no miras nunca si 34 es amigo de 42,

Citar
Fijate que nunca s y t llegan a ser iguales por eso no lanza el print.

Si pueden llegar a ser iguales para alguna entrada.

Charderak

Fijate lo que citó ghastlyX y su explicación.

Si no sabés utilizar un debugger, haz una prueba de escritorio :)


Título: Re: Programa para hallar números amigos
Publicado por: Charderak en 27 Junio 2010, 19:26 pm
Vale, más o menos creo que me he enterado y por lo menos ya tengo idea de por dónde puede andar el fallo, así que creo que es cuestión de ponerme a probar con las ideas que me habéis dado y acabar dando con la tecla

Voy a ello y luego os cuento, muchas gracias! :)