Reto en C

L

Ahi va:

Dos numeros son amigos si la suma de sus divisores
dan el otro numero y viceversa.

Ejemplo:
Divisors de 220: 1+2+4+5+10+11+20+22+44+55+110 = 284
Divisors de 284: 1+2+4+71+142 = 220

220 es amigo de 284(k mono! >_<")

Cuales son los numeros amigos del 1 al 10000??

Chungo?No!
Haber kien lo saca.

Sin mas un Salu2.

SouL

no lo tendrás que hacer pa clase no? xD

Aarseth

Aprende haskell y lo haces en 2 líneas, inútil.

n40k1

#3, Espero que seas amigo/conocido de #1, por que si no llamarte prepotente seria decirte poco...

Aarseth

Pues dime más, putot3.

K

Si logro hacer una función que me calcule los divisores de un número y los sume, tengo el programa hecho.

TeKaNeO

#include <stdio.h>
int divisores(int n);
void main()
{
int n;
int retorna;

printf("Introduce numero para calcular sus divisores\n");
scanf("%d",&n);
fflush(stdin);

retorna=divisores(n);

printf("La suma de sus divisores es: %d\n",retorna);

}

// Comienza funcion DIVISORES.

int divisores(int n)
{
int i=0;
int suma=0;

for(i=1;i<n;i++) // Incluye el 1 como divisor.
{
	if(n%i==0) // Si el resto de N/i da 0...
	{
		suma=suma+i;
	}
}
return suma;

}

Ahi la tienes, sigue xD

Saludos^^

K

#8, tu código me da una violación de segmento con el número 1, pero es curioso que solo cuando pongo Divisores(1), pero cuando "i" vale 1 en un bucle, no me falla :S

Lo he sacado ya, pero tengo que adivinar por qué cojones me hace el de 220 y el de 284, cuando supuestamente he hecho una cosa para que solo me saque una vez cada par.

LOc0

Si es que leo demasiado deprisa, y sin las gafas ¬¬...

A ver, calculas los divisores del primero (el 1) y los sumas. Entonces calculas los divisores de la suma y si coinciden con el 1 son amigos.

Calculas los divisores del segundo (el 2) y los sumas. Entonces calculas los divisores de la suma y compruebas si bla bla bla...

Así hasta el 10000.

Buena suerte.

Salu2 ;)

PD: Para optimizar puedes descartar los casos redundantes.

LoRTH

Pos no da errores ni na...
mv.c: En la funció "main":
mv.c:18: error: error sintàctic before "funcion"
mv.c:25: error: error sintàctic before "for"

Hay, estas universidades de pago que no enseñan a programar.. xDDDD

TeKaNeO

Lorth, con que lo compilas, uso Visual Studio 6.0 y esa funcion no falla, amos es una shorrada de funcion xD

LoRTH

Uso GCC, el compilador de GNU

Yo tengo una parte hecha del programa, xo no acaba de funcionar, osea hace todos los pasos, pero no encuentra numeros, xDDDD

K

Que basto el de ordenar el array...

A mí con GCC baja Linux no me da problema al compilar esa función... ¿Será que solo he copiado la función Divisores y no el programa completo?

LoRTH

Haber si veis mi error, no es de compilacion, sino de que hace como el proceso, pero no me saca los numeros:

#include <stdio.h>
#define MAX 10000
int contador1=0,contador2=0,contador,z,i;
void main(){
printf("\n\nEls números amics son:\n");
for(z=1;z<=MAX;z++){
for(i=1;i<MAX;i++){
if((z%i==0) && i< (z/2)) {
contador1=contador1+i;
}
}
for(i=1;i<MAX;i++){
if((contador1%i==0) && i< (contador/2)){
contador2=contador2+i;
}
}
if(z==contador2){
printf("%d i %d son nombres amics. \n",z,contador2);
}
}
}

P.D:lolmen, si te copias te mato. xD

K

LoRTH, no te compila porque él usa C++, y tú estás usando ANSI C. Hay cosas que debes pasar :)

Por cierto TeKaNeO, ¿Por qué no aprovechas y declaras el int dentro del for ya que CPP lo permite? Y el cin y el cout... Esas manías del C :) Por cierto, para los dos, "suma=suma+i;" sería lo mismo si pones "suma+=i;" Que conste que no os estoy corrigiendo ni nada, son simples apuntes ;)

http://usuarios.lycos.es/clanics/amigos.c

Compila perfectamente con GCC versión nosequé bajo Linux. Debería hacerlo en otros compiladores/SOs. Ojito con los saltos de línea, abridlo con un editor de texto de verdad.

Soy demasiado perro como para comentar bien mi código, pero sin embargo hago cabeceras chorras con cosas que no hacen ni puta gracia (Ni lo pretenden... Son simples formas de pasar el rato xD)

LOc0

// Calculador de números amigos, hecho por kaoD para Media-Vida blahblahblahblah
// Bajo licencia HLQTSDLH, "Haz Lo Que Te Salga De Los Huevos".
// No puedes encontrar la copia de la licencia por ningún lado, así que no la busques.

// Nota: Supuestamente debería mostrar solo una vez cada par, pero lo hace dos veces...
// ¿Por qué? Solo Jesucristo y Superman lo saben.

#define MAX 10000

int printf(const char *format, ...);

int sumaDivisores(int n) // Función por TeKaNeO
{
int i;
int suma=0;

for(i=1;i<n;i++) // Incluye el 1 como divisor.
{
	if(n%i==0) // Si el resto de N/i da 0...
	{
		suma=suma+i;
	}
}
return suma;

}

int main (void)
{
int number[MAX];
int sumai;
int sumaj;
int i;

printf("Calculando numeros amigos...\n");

for (i=1; i<=MAX; i++) // Pasa por todos los número del 1 al MAX
{
	if (number[i] != 1) // Si el número no se ha calculado ya
	{
		sumai = sumaDivisores(i); // Calcula la suma de sus divisores
		if (sumai <= MAX) // Si la suma de sus divisores es menor o igual a MAX
		{
			sumaj = sumaDivisores(sumai); // Calcula la suma de los divisores del número anteriormente obtenido.
			if (sumaj == i) // Muy largo de explicar xD
			{
				number[sumai] == 1;
				printf("%d - %d\n",sumai,sumaj);
			}
		}
	}
}
return 0;

}[/i]

number[sumai] = 1;

Salu2 ;)

K

Ostia tio, que cagada más tonta :) Siempre he odiado la historia del = y el == xD Muchas gracias.

Ya está subido corregido.

1.581s en calcular los números amigos del 1 al 10000 con un Pentium 4 a 2.8GHz.

LOc0

#18

Si tienes ganas de hacer benchmarks podrías echarme una mano con --> www.ecuacionimposible.tk xDD

Salu2 ;)

K

#19, si me lo compilas para Linux o me pasas el código (Preferiblemente compatible con Linux* o ya portado xD), encantado ;)

*Si es C a secas, sin librerías raras de Windows, debería funcionar sin portar.

E

// Nota: Supuestamente debería mostrar solo una vez cada par, pero lo hace dos veces...
// ¿Por qué? Solo Jesucristo y Superman lo saben.

-> Porque los amigos son mutuos. Si llegas a a y <U>a[/u] es amigo de b, muestra a. Luego llegará a b, calculará su amigo, y lo mostrará (a).

LOc0

#20

El "único" problemilla para Linux es conio.h, pero claro, para hacerlo más"bonito" casi todas las salidas de consola la usan... En cuanto tenga tiempo lo porto.

Salu2 ;)

PD: El problema gordo que veo ahora para portarlo a Linux es que no conozco una función equivalente a KBHIT(), que sirve para detectar si una tecla es pulsada (sin detener la ejecución del programa) :( :(

K

#21, eso ya me lo respondió #17...

Lo que tú dices ya lo sabía, pero es que en el código una parte se ocupa precisamente de no mostrarte dos veces cada par (Uno con inicio en el primer número, y otro con el otro) calculando solo usando el primer número... El caso es que me había equivocado en una parte y no cambiaba el valor de una variable, sino que solo lo "comprobaba".

PD: Hasta 100000 tarda un poquito más, 2m37.149s

[EDIT]

Para el KBHIT, http://www.google.es/search?q=KBHIT+linux&start=0&start=0&ie=utf-8&oe=utf-8

LOc0

LOL, lo que no venga en Google diectamente no es real :)...

Ahora portarlo es sólo cuestión de perrería xD

Salu2 ;)

EDITADO: Kaod ¿te compila bien esto?-->

kbhit.c


/* ***************************************************************************
*

  • Copyright 1992-2005 by Pete Wilson All Rights Reserved
  • 50 Staples Street : Lowell Massachusetts 01851 : USA
  • http://www.pwilson.net/ pete@pwilson.net +1 978-454-4547
    *
  • This item is free software: you can redistribute it and/or modify it as
  • long as you preserve this copyright notice. Pete Wilson prepared this item
  • hoping it might be useful, but it has NO WARRANTY WHATEVER, not even any
  • implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *************************************************************************** */

/* ***************************************************************************
*

  • KBHIT.C
    *
  • Based on the work of W. Richard Stevens in "Advanced Programming in
  • the Unix Environment," Addison-Wesley; and of Floyd Davidson.
    *
  • Contains these functions:
    *
  • To set the TTY mode:
  • tty_set_raw() Unix setup to read a character at a time.
  • tty_set_cooked() Unix setup to reverse tty_set_raw()
    *
  • To read keyboard input:
  • kb_getc() keyboard get character, NON-BLOCKING. If a char
  • has been typed, return it. Else return 0.
  • kb_getc_w() kb get char with wait: BLOCKING. Wait for a char
  • to be typed and return it.
    *
  • How to use:
  • tty_set_raw() set the TTY mode to read one char at a time.
  • kb_getc() read chars one by one.
  • tty_set_cooked() VERY IMPORTANT: restore cooked mode when done.
    *
  • Revision History:
    *
  • DATE DESCRIPTION
  • ----------- --------------------------------------------
  • 12-jan-2002 new
  • 20-aug-2002 cleanup
    *
  • Notes:
  • ----------- --------------------------------------------
  • 25-nov-2003 notate anomoly in some Unices: termattr.c_cc[VMIN] = 0;
    *************************************************************************** */

#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include
#include <errno.h>

#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif

extern int errno;

static struct termios termattr, save_termattr;
static int ttysavefd = -1;
static enum
{
RESET, RAW, CBREAK
} ttystate = RESET;

/* ***************************************************************************
*

  • set_tty_raw(), put the user's TTY in one-character-at-a-time mode.

  • returns 0 on success, -1 on failure.
    *
    *************************************************************************** */
    int
    set_tty_raw(void)
    {
    int i;

    i = tcgetattr (STDIN_FILENO, &termattr);
    if (i < 0)
    {
    printf("tcgetattr() returned %d for fildes=%d\n",i,STDIN_FILENO);
    perror ("");
    return -1;
    }
    save_termattr = termattr;

    termattr.c_lflag &= ECHO | ICANON | IEXTEN | ISIG;
    termattr.c_iflag &= BRKINT | ICRNL | INPCK | ISTRIP | IXON;
    termattr.c_cflag &= CSIZE | PARENB);
    termattr.c_cflag |= CS8;
    termattr.c_oflag &= OPOST;


    termattr.c_cc[VMIN] = 1; /* or 0 for some Unices; see note 1 */
    termattr.c_cc[VTIME] = 0;

    i = tcsetattr (STDIN_FILENO, TCSANOW, &termattr);
    if (i < 0)
    {
    printf("tcsetattr() returned %d for fildes=%d\n",i,STDIN_FILENO);
    perror("");
    return -1;
    }


    ttystate = RAW;
    ttysavefd = STDIN_FILENO;

    return 0;
    }

/* ***************************************************************************
*

  • set_tty_cbreak(), put the user's TTY in cbreak mode.

  • returns 0 on success, -1 on failure.
    *
    *************************************************************************** */
    int
    set_tty_cbreak()
    {
    int i;

    i = tcgetattr (STDIN_FILENO, &termattr);
    if (i < 0)
    {
    printf("tcgetattr() returned %d for fildes=%d\n",i,STDIN_FILENO);
    perror ("");
    return -1;
    }

    save_termattr = termattr;

    termattr.c_lflag &= ECHO | ICANON;
    termattr.c_cc[VMIN] = 1;
    termattr.c_cc[VTIME] = 0;


    i = tcsetattr (STDIN_FILENO, TCSANOW, &termattr);
    if (i < 0)
    {
    printf("tcsetattr() returned %d for fildes=%d\n",i,STDIN_FILENO);
    perror ("");
    return -1;
    }
    ttystate = CBREAK;
    ttysavefd = STDIN_FILENO;

    return 0;
    }

/* ***************************************************************************
*

  • set_tty_cooked(), restore normal TTY mode. Very important to call
  • the function before exiting else the TTY won't be too usable.
  • returns 0 on success, -1 on failure.
    *
    *************************************************************************** */
    int
    set_tty_cooked()
    {
    int i;
    if (ttystate != CBREAK && ttystate != RAW)
    {
    return 0;
    }
    i = tcsetattr (STDIN_FILENO, TCSAFLUSH, &save_termattr);
    if (i < 0)
    {
    return -1;
    }
    ttystate = RESET;
    return 0;
    }

/* ***************************************************************************
*

  • kb_getc(), if there's a typed character waiting to be read,

  • return it; else return 0.
    *
    *************************************************************************** */
    unsigned char
    kb_getc(void)
    {
    unsigned char ch;
    ssize_t size;

    size = read (STDIN_FILENO, &ch, 1);
    if (size == 0)
    {
    return 0;
    }
    else
    {
    return ch;
    }
    }

/* ***************************************************************************
*

  • kb_getc_w(), wait for a character to be typed and return it.
    *
    *************************************************************************** */
    unsigned char
    kb_getc_w(void)
    {
    unsigned char ch;
    size_t size;

    while (1)
    {

    usleep(20000); /* 1/50th second: thanks, Floyd! */

    size = read (STDIN_FILENO, &ch, 1);
    if (size > 0)
    {
    break;
    }
    }
    return ch;
    }

#define TEST
#ifdef TEST

void echo(unsigned char ch);

static enum
{
CH_ONLY, CH_HEX
} how_echo = CH_ONLY;

int
main(int argc, char * argv[])
{
unsigned char ch;

printf("Test Unix single-character input.\n");

set_tty_raw(); /* set up character-at-a-time */


while (1) /* wait here for a typed char /
{
usleep(20000); /
1/50th second: thanks, Floyd! /
ch = kb_getc(); /
char typed by user? /
if (0x03 == ch) /
might be control-C /
{
set_tty_cooked(); /
control-C, restore normal TTY mode /
return 1; /
and get out /
}
echo(ch); /
not control-C, echo it */
}
}

void
echo(unsigned char ch)
{
switch (how_echo)
{
case CH_HEX:
printf("%c,0x%x ",ch,ch);
break;
default:
case CH_ONLY:
printf("%c", ch);
break;
}

fflush(stdout); /* push it out */
}

#endif /* test */

#ifdef __cplusplus
}
#endif

[/i]

Salu2 ;)

K

Sorry, ya no me da tiempo a probarlo, mañana lo hago :)

L

W0w!! In-creible
Mu currado estan todos.
Muchas gracias a todos por la ayuda!

Salu2

LoRTH

Por cierto, ya me va, xD

cabron

No es por nada, pero le habéis hecho los deberes...

Usuarios habituales

  • LoRTH
  • lolmen
  • kaoD2
  • LOc0
  • TeKaNeO
  • Aarseth
  • SouL