TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Nocturno en 28 de Mayo de 2013, 04:11:05

Título: Concurso de programación: números romanos
Publicado por: Nocturno en 28 de Mayo de 2013, 04:11:05
Hola amigos, he organizado un concurso de programación en MicroPIC en el que estaré encantado de que participéis, cuantos más mejor.

El objetivo es en diseñar el algoritmo más rápido de conversión a números romanos.

¡SUERTE!

http://www.micropic.es/mpblog/2013/05/primer-concurso-de-programacion-micropic-numeros-romanos/
Título: Re: Concurso de programación: números romanos
Publicado por: samshiel_pic en 28 de Mayo de 2013, 09:08:46
 ((:-)) Voy a intentarlo, paisano!! buena idea de concurso para animar el foro en su cumple!!
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 28 de Mayo de 2013, 11:56:53
Yo no utilizo Proteus ni CCS, por lo que no puedo poner la captura de pantalla, pero aquí está mi código:
A ver si alguien se ofrece a compilarlo y probarlo.


Código: [Seleccionar]
#define PUTCH(c)  {while (!txif);  txreg = c; }

void ConvierteARomano(int16 Numero) {        
   int8 Num;
   if (Numero>>8) {
      while (Numero >= 1000) {
         PUTCH('M');
         Numero -= 1000;
      }
      if (Numero >= 900) {
         PUTCH('C');
         PUTCH('M');
         Numero -= 900;
      }
      if (Numero >= 500) {
         PUTCH('D');
         Numero -= 500;
      }
      if (Numero >= 400) {
         PUTCH('C');
         PUTCH('D');
         Numero -= 400;
      }
      while(Numero>>8) {
         PUTCH('C');
         Numero -= 100;
      };
   }
   Num = Numero;
   while(Num >= 100) {
      PUTCH('C');
      Numero -= 100;
   };
   if (Num >= 90) {
      PUTCH('X');
      PUTCH('C');
      Num -= 90;
   }
   if (Num >= 50) {
      PUTCH('L');
      Num -= 50;
   }
   if (Num >= 40) {
      PUTCH('X');
      PUTCH('L');
      Num -= 40;
   }
   while(Num >= 10) {
      PUTCH('X');
      Num -= 10;
   };
   if (Num >= 9) {
      PUTCH('I');
      PUTCH('X');
      Num -= 90;
   }
   if (Num >= 5) {
      PUTCH('V');
      Num -= 5;
   }
   if (Num >= 4) {
      PUTCH('I');
      PUTCH('V');
      Num -= 4;
   }
   while(Num > 0) {
      PUTCH('I');
      Num--;
   }  
}

El truco para optimizar mi algoritmo está en comenzar a transmitir cuanto antes el primer caracter.
Una vez que se está transmitiendo un caracter a 9600baud, tenemos tiempo suficiente para realizar los cálculos del siguiente caracter.

Saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 28 de Mayo de 2013, 13:01:16
Lo he probado y no funciona, Picuino.
Lo hace bien con el número 54, pero al convertir el 1238 sale una M seguida de infinitas C

Para poder compilarlo en CCS he tenido que modificar el define que tenías por este otro:
#define PUTCH(c)  putc(c)
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 28 de Mayo de 2013, 13:13:56
No conozco bien cómo acceder a los registros TXIF y TXREG en CCS, pero la idea es ahorrar un salto a putch(c) para ser más rápido.

Voy a intentar corregirlo.

Mientras tanto se me ha ocurrido otra idea para ahorrar pulsos: pasar al micro a idle después de enviar un caracter (el timer dejará de contar pulsos) y despertarle con la interrupción de la usart cuando termine de enviar el caracter.

Saludos.

P.D. Gracias por compilarlo Nocturno

Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 28 de Mayo de 2013, 13:32:41
Así es como se usan los registros en CCS, pero se queda parado sin imprimir nada.

#byte PIR1=0xF9E
#bit txif=PIR1.4
#byte txreg=0xFAD
#define PUTCH(c)  {while(!txif);txreg=c;}

El truco que comentas para alterar el Timer es interesante, pero no haría más rápido al algoritmo, sólo falsearía el recuento del timer.
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 28 de Mayo de 2013, 13:38:19
El código tenía dos erratas.
Este está probado en un compilador de c y funciona.

Código: [Seleccionar]
void ConvierteARomano(int16 Numero) {
   unsigned char Num;

   if (Numero>>8) {
      while (Numero >= 1000) {
         PUTCH('M');
         Numero -= 1000;
      }
      if (Numero >= 900) {
         PUTCH('C');
         PUTCH('M');
         Numero -= 900;
      }
      if (Numero >= 500) {
         PUTCH('D');
         Numero -= 500;
      }
      if (Numero >= 400) {
         PUTCH('C');
         PUTCH('D');
         Numero -= 400;
      }
      while(Numero>>8) {
         PUTCH('C');
         Numero -= 100;
      };
   }
   Num = Numero;
   while(Num >= 100) {
      PUTCH('C');
      Num -= 100;
   };
   if (Num >= 90) {
      PUTCH('X');
      PUTCH('C');
      Num -= 90;
   }
   if (Num >= 50) {
      PUTCH('L');
      Num -= 50;
   }
   if (Num >= 40) {
      PUTCH('X');
      PUTCH('L');
      Num -= 40;
   }
   while(Num >= 10) {
      PUTCH('X');
      Num -= 10;
   };
   if (Num >= 9) {
      PUTCH('I');
      PUTCH('X');
      Num -= 9;
   }
   if (Num >= 5) {
      PUTCH('V');
      Num -= 5;
   }
   if (Num >= 4) {
      PUTCH('I');
      PUTCH('V');
      Num -= 4;
   }
   while(Num > 0) {
      PUTCH('I');
      Num--;
   }
}

Habría que definir PUTCH(c) como una macro muy rápida que compruebe TXIF y escriba TXREG. En C18 se hace asi:
#define PUTCH(c)  {while (PIR1bits.TXIF == 0);   TXREG = c; }

Nocturno: probablemente no funciona porque la primera vez hay que forzar TXIF a uno:


Saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 28 de Mayo de 2013, 13:45:21
txif hay que forzarlo a uno antes del programa principal. Este es el programa completo:

Código: [Seleccionar]
#include <18F458.h>
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES OSCSEN                   //Oscillator switching is enabled
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=8000000)

#use rs232(baud=9600,XMIT=PIN_C6)
#include <string.h>

int16 ListaNumeros[10]={54,1238,41,2500,640,99,1,999,1001,2666};

int16 Contador=0;


#byte PIR1=0xF9E
#bit txif=PIR1.4
#byte txreg=0xFAD
#define PUTCH(c)  { while(txif==0); txreg=c; }

void ConvierteARomano(int16 Numero) {
   unsigned char Num;

   if (Numero>>8) {
      while (Numero >= 1000) {
         PUTCH('M');
         Numero -= 1000;
      };
      if (Numero >= 900) {
         PUTCH('C');
         PUTCH('M');
         Numero -= 900;
      }
      if (Numero >= 500) {
         PUTCH('D');
         Numero -= 500;
      }
      if (Numero >= 400) {
         PUTCH('C');
         PUTCH('D');
         Numero -= 400;
      }
      while(Numero>>8) {
         PUTCH('C');
         Numero -= 100;
      };
   }
   Num = Numero;
   while(Num >= 100) {
      PUTCH('C');
      Num -= 100;
   };
   if (Num >= 90) {
      PUTCH('X');
      PUTCH('C');
      Num -= 90;
   }
   if (Num >= 50) {
      PUTCH('L');
      Num -= 50;
   }
   if (Num >= 40) {
      PUTCH('X');
      PUTCH('L');
      Num -= 40;
   }
   while(Num >= 10) {
      PUTCH('X');
      Num -= 10;
   };
   if (Num >= 9) {
      PUTCH('I');
      PUTCH('X');
      Num -= 9;
   }
   if (Num >= 5) {
      PUTCH('V');
      Num -= 5;
   }
   if (Num >= 4) {
      PUTCH('I');
      PUTCH('V');
      Num -= 4;
   }
   while(Num > 0) {
      PUTCH('I');
      Num--;
   };
}


#INT_TIMER1
void Incrementa_Contador() {
   Contador++;
}

void main()
{
   int i;
   int16 Duracion;
  
   setup_timer_1 ( T1_INTERNAL);


   printf ("Primer concurso de programacion. NUMEROS ROMANOS\n\r");
   printf ("www.micropic.es\n\r\n\r");
   set_timer1(0);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);

   txif = 1;   // Reset de la USART

   for (i=0;i<10;i++) {
      printf ("%LU = ",ListaNumeros[i]);
      ConvierteARomano(ListaNumeros[i]);
      printf ("\n\r");
   }
   Duracion=get_timer1();
   printf ("Ha tardado %LU ticks\n\r",make32(Contador,Duracion));
   while(TRUE);

}

Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 28 de Mayo de 2013, 13:47:41
Pues sigue pasando lo mismo, no imprime. Pero es posible que se trate de un bug de Proteus, no me fío mucho.

Si quieres, lo dejo con el putc, que al menos imprimía, aunque falla al traducir el número 1238.
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 28 de Mayo de 2013, 13:51:51
 :shock: esta vez no sé porqué falla.
en mi compilador de c el 1238 lo traduce como MCCXXXVIII

Puede que esté relacionado con la asignación a Num del byte bajo de Numero. ¿Quizás hay que definir Num como un unsigned int8?

Si no funciona, pon el putch(), aunque va a ser mucho más lento.

Gracias por compilarlo.

Saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 28 de Mayo de 2013, 13:54:38
Tienes razón, el algoritmo ya funciona, no había leído tu comentario de las dos erratas.
Pero para imprimir he tenido que usar el putc.

Aquí dejo la captura de pantalla provisional, si consigo resolver lo del tratamiento de registros volveré a informar.
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 28 de Mayo de 2013, 14:09:19
Así es como lo compila CCS.
....................          PUTCH('C');
00F4:  BTFSS  F9E.4
00F6:  BRA    00F4
00F8:  MOVLW  43
00FA:  MOVWF  FAD
....................          PUTCH('M');
00FC:  BTFSS  F9E.4
00FE:  BRA    00FC
0100:  MOVLW  4D
0102:  MOVWF  FAD

Se queda enganchado en el BTFSS y BRA. Se ve que el bit no cambia de valor.
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 28 de Mayo de 2013, 14:20:48
No creo que se pueda mejorar.

Esas instrucciones equivalen a lo que yo quería hacer.


y he conseguido un buen tiempo  :-/

Saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 28 de Mayo de 2013, 14:24:49
No, esas instrucciones es como compila tu código original, pero no funciona en la simulación.
El tiempo que has conseguido en la captura de pantalla que antes adjunté está logrado con putc.
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 28 de Mayo de 2013, 14:29:26
Bueno, por ahora sólo queda que alguien aporte uno mejor  ;-)


Saludos
Título: Re: Concurso de programación: números romanos
Publicado por: Tisco en 28 de Mayo de 2013, 14:30:03
Es una pena que el concurso sea en CCS, si no participaría.  :(

Suerte a tod@s!
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 28 de Mayo de 2013, 14:41:35
Pásame tu función en C y yo la adapto a CCS si fuera necesario.

Aquí está ya tu participación, Picuino (http://www.micropic.es/mpforo/index.php?topic=1475.msg7111#msg7111)
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 28 de Mayo de 2013, 15:03:11
Gracias Nocturno.
Título: Re: Concurso de programación: números romanos
Publicado por: Suky en 28 de Mayo de 2013, 21:34:55
Y si cambian el macro a:

Código: C
  1. #byte TXSTA=0xFAC
  2. #bit TRMT=TXSTA.1
  3. #byte TXREG=0xFAD
  4. #define PUTCH(c)  { while(TRMT==0); TXREG=c;}

 :huh:

También se le podria agregar en el macro una linea como set_timer1(0)  :D

Saludos!
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 29 de Mayo de 2013, 01:42:22
También probé eso, Suky, pero se queda enganchado. En cuanto pueda lo monto físicamente, porque estoy casi seguro que va a ser un problema de la simulación.

Lo del set_timer batiría todos los records  :D ... y justo después sería descalificado :lol:
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 29 de Mayo de 2013, 01:57:50
Actualizo. He probado el código de Picuino también con MPLAB SIM, del cual me fío bastante más que de Proteus, y también se queda enganchado en el mismo punto.

Intentando ver cómo funciona el putc(), este es el código ASM que genera. No entiendo ASM, pero no veo ninguna escritura en el registro TXREG (0xFAD) en todo ese trozo de código, así que no sé cómo furula, pero creo que ahí está la clave.

Código: ASM
  1. 0122    9C94     BCF 0xf94, 0x6, ACCESS
  2.   0124    9C8B     BCF 0xf8b, 0x6, ACCESS
  3.   0126    0E08     MOVLW 0x8
  4.   0128    6E01     MOVWF 0x1, ACCESS
  5.   012A    D000     BRA 0x12c
  6.   012C    0000     NOP
  7.   012E    8E01     BSF 0x1, 0x7, ACCESS
  8.   0130    D00E     BRA 0x14e
  9.   0132    9E01     BCF 0x1, 0x7, ACCESS
  10.   0134    3244     RRCF 0x44, F, ACCESS
  11.   0136    B0D8     BTFSC 0xfd8, 0, ACCESS
  12.   0138    8C8B     BSF 0xf8b, 0x6, ACCESS
  13.   013A    A0D8     BTFSS 0xfd8, 0, ACCESS
  14.   013C    9C8B     BCF 0xf8b, 0x6, ACCESS
  15.   013E    8C01     BSF 0x1, 0x6, ACCESS
  16.   0140    D006     BRA 0x14e
  17.   0142    9C01     BCF 0x1, 0x6, ACCESS
  18.   0144    2E01     DECFSZ 0x1, F, ACCESS
  19.   0146    D7F6     BRA 0x134
  20.   0148    D000     BRA 0x14a
  21.   014A    0000     NOP
  22.   014C    8C8B     BSF 0xf8b, 0x6, ACCESS
  23.   014E    0E3F     MOVLW 0x3f
  24.   0150    6EE9     MOVWF 0xfe9, ACCESS
  25.   0152    2EE9     DECFSZ 0xfe9, F, ACCESS
  26.   0154    D7FE     BRA 0x152
  27.   0156    0000     NOP
  28.   0158    BE01     BTFSC 0x1, 0x7, ACCESS
  29.   015A    D7EB     BRA 0x132
  30.   015C    BC01     BTFSC 0x1, 0x6, ACCESS
  31.   015E    D7F1     BRA 0x142
  32.   0160    0012     RETURN 0
Título: Re: Concurso de programación: números romanos
Publicado por: gab163 en 29 de Mayo de 2013, 04:36:24
Bueno revisando logre conseguir esto espero este bueno te mando el código al correo.



Nocturno, por ahí envié uno con un error pero lo corregir y lo volví a mandar saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 29 de Mayo de 2013, 08:58:18
Actualizo. He probado el código de Picuino también con MPLAB SIM, del cual me fío bastante más que de Proteus, y también se queda enganchado en el mismo punto.

Intentando ver cómo funciona el putc(), este es el código ASM que genera. No entiendo ASM, pero no veo ninguna escritura en el registro TXREG (0xFAD) en todo ese trozo de código, así que no sé cómo furula, pero creo que ahí está la clave.

Código: ASM
  1. 0122    9C94     BCF 0xf94, 0x6, ACCESS
  2.  0124    9C8B     BCF 0xf8b, 0x6, ACCESS
  3.  0126    0E08     MOVLW 0x8
  4.  0128    6E01     MOVWF 0x1, ACCESS
  5.  012A    D000     BRA 0x12c
  6.  012C    0000     NOP
  7.  012E    8E01     BSF 0x1, 0x7, ACCESS
  8.  0130    D00E     BRA 0x14e
  9.  0132    9E01     BCF 0x1, 0x7, ACCESS
  10.  0134    3244     RRCF 0x44, F, ACCESS
  11.  0136    B0D8     BTFSC 0xfd8, 0, ACCESS
  12.  0138    8C8B     BSF 0xf8b, 0x6, ACCESS
  13.  013A    A0D8     BTFSS 0xfd8, 0, ACCESS
  14.  013C    9C8B     BCF 0xf8b, 0x6, ACCESS
  15.  013E    8C01     BSF 0x1, 0x6, ACCESS
  16.  0140    D006     BRA 0x14e
  17.  0142    9C01     BCF 0x1, 0x6, ACCESS
  18.  0144    2E01     DECFSZ 0x1, F, ACCESS
  19.  0146    D7F6     BRA 0x134
  20.  0148    D000     BRA 0x14a
  21.  014A    0000     NOP
  22.  014C    8C8B     BSF 0xf8b, 0x6, ACCESS
  23.  014E    0E3F     MOVLW 0x3f
  24.  0150    6EE9     MOVWF 0xfe9, ACCESS
  25.  0152    2EE9     DECFSZ 0xfe9, F, ACCESS
  26.  0154    D7FE     BRA 0x152
  27.  0156    0000     NOP
  28.  0158    BE01     BTFSC 0x1, 0x7, ACCESS
  29.  015A    D7EB     BRA 0x132
  30.  015C    BC01     BTFSC 0x1, 0x6, ACCESS
  31.  015E    D7F1     BRA 0x142
  32.  0160    0012     RETURN 0


Ese código implementa directamente la escritura de los bits en la salida TX (LATCbits.LATC6 = F8B.6), sin utilizar la USART. A los 8 bits del caracter le añade un bit a cero de comienzo y un bit a uno de finalización.
El problema de esta rutina es que el micro no puede hacer nada mientras se transmite el caracter.

Saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 29 de Mayo de 2013, 11:34:57
Pues entonces ya está todo claro: CCS estaba emulando el puerto serie en vez de utilizar la USART.
Ya lo he resuelto en el programa base y mira cómo queda tu resultado ahora:
http://www.micropic.es/mpforo/index.php?topic=1475.msg7114#msg7114
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 29 de Mayo de 2013, 12:02:36
Guau :shock:
Ahora si que va rápido.

Al final te vas a llevar tú el premio, Nocturno  :D

Saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 29 de Mayo de 2013, 12:19:43
De momento te gano  :D

Tengo una rutina que ahorra unos ciclos respecto a la tuya, a pesar de utilizar printf en lugar del txreg.
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 29 de Mayo de 2013, 15:26:29
Creo que el punto a mejorar en mi programa es comenzar cuanto antes a transmitir el primer caracter, pero no se me ocurre cómo hacerlo.
Quizás con una división de Número y luego utilizar un array con las letras correspondientes...

Por ahora lo dejo como está.

Saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: BrunoF en 29 de Mayo de 2013, 20:50:33
Se me ocurren cosas muy locas. Voy a ver si salgo con alguna de ellas.

Saludos!
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 30 de Mayo de 2013, 01:54:50
Este es tu resultado, Bruno

http://www.micropic.es/mpforo/index.php?topic=1475.msg7120#msg7120
Título: Re: Concurso de programación: números romanos
Publicado por: BrunoF en 30 de Mayo de 2013, 02:07:00
Buuu! Exijo un recuento de ticks! Me ha dado mucho menos en mis pruebas!
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 30 de Mayo de 2013, 06:37:34
No entiendo lo que pasa, Don Bruno.
Lo estoy simulando con MPLAB SIM (ya he aprendido a hacer printf en el debugger) y lo he compilado con las versiones 4.119, 4.124, 4.134 y 4.140.

En todos los casos el resultado es este:
Primer concurso de programacion. NUMEROS ROMANOS

www.micropic.es


54 = LIV

1238 = MCCXXXVIII

41 = XLI

2500 = MMD

640 = DCXL

99 = XCIX

1 = I

999 = CMXCIX

1001 = MI

2666 = MMDCLXVI

Ha tardado 321368 ticks
Título: Re: Concurso de programación: números romanos
Publicado por: MGLSOFT en 30 de Mayo de 2013, 08:11:41
Lo que pasa es que aqui en Argentina todo es mas rapido que en Europa !!  :D :D :lol: :lol:
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 30 de Mayo de 2013, 10:09:34
Pues no estarán muy contentas las argentinas con eso   :D
Título: Re: Concurso de programación: números romanos
Publicado por: MGLSOFT en 30 de Mayo de 2013, 10:27:42
15 en lugar de 3 te parece mal ??   :shock: :shock: ;-) ;-)
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 30 de Mayo de 2013, 11:50:44
Si hablas de frecuencia no está mal, pero si hablas de periodo, 15 semanas es mucho.
Título: Re: Concurso de programación: números romanos
Publicado por: MGLSOFT en 30 de Mayo de 2013, 12:06:52
je!! :D
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 30 de Mayo de 2013, 14:23:00
Tras la participación de Bruno, hemos visto que las diferencias en los distintos algoritmos son muy escasas, lo cual era sumamente sospechoso.

Bruno ha llegado a la conclusión de que el principal consumo de tiempo se debía a la impresión de los resultados con la USART, por lo que la influencia del algoritmo quedaba completamente oculta bajo las esperas de la USART.

La solución para medir perfectamente la eficacia de los distintos algoritmos pasa por hacer una modificación al funcionamiento, que ha consistido en que la función devuelva el resultado en un string de 16 posiciones.

char Resultado[16];

Puedes descargar la nueva plantilla desde aquí (http://www.micropic.es/mpforo/index.php?action=dldir;sa=details;lid=197)

Para no marear a los concursantes que ya han enviado su algoritmo, haré yo las modificaciones y publicaré los resultados.

Por cierto, este es el resultado de Bruno con su algoritmo:
(http://img850.imageshack.us/img850/699/resultadobruno.jpg)
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 30 de Mayo de 2013, 15:50:03
Ya están publicados los resultados de los distintos algoritmos con la nueva estructura.
Podéis verlos aquí:

http://www.micropic.es/mpforo/index.php?topic=1475.msg7124#msg7124

Ahora mismo se sitúa en cabeza Picuino, seguido de cerca por Bruno
Título: Re: Concurso de programación: números romanos
Publicado por: MGLSOFT en 30 de Mayo de 2013, 16:17:48
Ahora el tiempo medido es solo el de la conversión a romano, ya sin impresion??
Título: Re: Concurso de programación: números romanos
Publicado por: BrunoF en 30 de Mayo de 2013, 16:21:36
Si.

Parece que no voy a ganar, pero que hasta el momento es el más rebuscado, estoy seguro que sí. Pensé que iba a ser más veloz.
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 30 de Mayo de 2013, 17:32:07
Viva el open-source  :-/

Mi algoritmo está publicado aquí  ;-) :

http://www.todopic.com.ar/foros/index.php?topic=40865.msg339997#msg339997

Saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 30 de Mayo de 2013, 17:39:57
Dejo el nuevo algoritmo modificado, bajo licencia GNU GPL (http://www.gnu.org/licenses/gpl.html) (se puede utilizar siempre que se publique el algoritmo modificado)

Código: C
  1. void ConvierteARomano(int16 Numero) {
  2.     unsigned char Num;
  3.     unsigned int8 posicion = 0;
  4.      
  5.     #define PUTCH(c) Resultado[posicion++]=c
  6.      
  7.       if (Numero>>8) {
  8.          while (Numero >= 1000) {
  9.             PUTCH('M');
  10.             Numero -= 1000;
  11.          }
  12.          if (Numero >= 900) {
  13.             PUTCH('C');
  14.             PUTCH('M');
  15.             Numero -= 900;
  16.          }
  17.          if (Numero >= 500) {
  18.             PUTCH('D');
  19.             Numero -= 500;
  20.          }
  21.          if (Numero >= 400) {
  22.             PUTCH('C');
  23.             PUTCH('D');
  24.             Numero -= 400;
  25.          }
  26.          while(Numero>>8) {
  27.             PUTCH('C');
  28.             Numero -= 100;
  29.          };
  30.       }
  31.       Num = Numero;
  32.       while(Num >= 100) {
  33.          PUTCH('C');
  34.          Num -= 100;
  35.       };
  36.       if (Num >= 90) {
  37.          PUTCH('X');
  38.          PUTCH('C');
  39.          Num -= 90;
  40.       }
  41.       if (Num >= 50) {
  42.          PUTCH('L');
  43.          Num -= 50;
  44.       }
  45.       if (Num >= 40) {
  46.          PUTCH('X');
  47.          PUTCH('L');
  48.          Num -= 40;
  49.       }
  50.       while(Num >= 10) {
  51.          PUTCH('X');
  52.          Num -= 10;
  53.       };
  54.       if (Num >= 9) {
  55.          PUTCH('I');
  56.          PUTCH('X');
  57.          Num -= 9;
  58.       }
  59.       if (Num >= 5) {
  60.          PUTCH('V');
  61.          Num -= 5;
  62.       }
  63.       if (Num >= 4) {
  64.          PUTCH('I');
  65.          PUTCH('V');
  66.          Num -= 4;
  67.       }
  68.       while(Num > 0) {
  69.          PUTCH('I');
  70.          Num--;
  71.       }
  72.       Resultado[posicion] = '\0';
  73.     }

Saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: BrunoF en 30 de Mayo de 2013, 17:48:56
Hombre, que si bien tener open source ayuda casi siempre, aquí también puede impidir y condicionar el desarrollo de la imaginación.

Felicitaciones por llevar la punta.
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 30 de Mayo de 2013, 18:04:15
Si aparecen más códigos publicados, eso al final estimula a combinar ideas y hacer nuevos programas.
No es obligatorio seguir mi código, puede utilizarse como base para nuevas ideas que no lo copien.

Saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: gab163 en 31 de Mayo de 2013, 01:14:32
Bueno con algunas ideas nuevas, tomando como idea la asignación de datos de Picuino adapte un pequeño algoritmo de búsqueda para evitar algunas comparaciones se deja el codigo  bajo licencia GNU GPL como comento Picuino y pues a seguir depurando. Esto es lo que resulto:

Código: [Seleccionar]
void ConvierteARomano(int16 Numero) {
unsigned char Num;
    unsigned int8 posicion = 0;
    #define PUTCH(c) Resultado[posicion++]=c
    
    if(Numero>>8){
//*********************Miles****************************************************
         if(Numero>=1000){
            while(Numero>=1000){
            Numero-=1000;
            PUTCH('M');
            }
         }
//*********************Cientos**************************************************        
         if(Numero>=100){
            if(Numero>=500){
               if(Numero>=900){PUTCH('C');PUTCH('M');Numero-=900;}
               else{PUTCH('D');Numero-=500;}
            }
            if(Numero>=400){PUTCH('C');PUTCH('D');Numero-=400;}
            while(Numero>>8){PUTCH('C');Numero-=100;}
         }
    }
    Num=Numero;
    while(Num>=100){PUTCH('C');Num-=100;}
//***********************Decenas************************************************    
    if(Num>=50){
         if(Num>=90){PUTCH('X');PUTCH('C');Num-=90;}
         else{PUTCH('L');Num-=50;}
    }
    if(Num>=40){PUTCH('X');PUTCH('L');Num-=40;}
    while(Num>=10){PUTCH('X');Num-=10;}
//******************************Unidades****************************************
    if(Num){
         if(Num>5){
               if(Num==9){PUTCH('I');PUTCH('X');Num-=9;}
               else{PUTCH('V');Num-=5;}
         }
         if(Num==4){PUTCH('I');PUTCH('V');Num-=4;}
         while(Num){PUTCH('I');Num-=1;}
         }
//******************************************************************************        
     Resultado[posicion] = '\0';
  }
(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=40865.0;attach=20695;image)
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 31 de Mayo de 2013, 05:24:54
¡Venga, vamos!, que todavía se puede optimizar bastante.

Os paso el resultado de mi algoritmo, que lógicamente está fuera de concurso. Como pista os diré que no se parece en absoluto a ninguno de los vuestros.

(http://img594.imageshack.us/img594/8836/resultadonocturno.jpg)
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 31 de Mayo de 2013, 18:49:22
Se me ha ocurrido utilizar la conversión de binario a BCD como paso previo para convertir a romanos.

En cuanto tenga un rato libre intento desarrollarlo.

Saludos.
Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 11 de Junio de 2013, 12:17:31
Amigos, tenemos nuevo líder.

El algoritmo que me ha enviado Hugo Ernesto obtiene un resultado de 67592 y se pone en cabeza.

Vamos, que quedan pocos días. A darle duro.

(http://img405.imageshack.us/img405/3261/resultadohugoernesto.jpg)
Título: Re: Concurso de programación: números romanos
Publicado por: Picuino en 11 de Junio de 2013, 14:09:22
Me fastidia no tener mucho tiempo.
Ahora estoy hasta arriba con un montón de temas pendientes y no puedo dedicarle tiempo.

A ver si este finde puedo darle un último empujon.

Felicidades a Hugo (por ahora) ;-)

Saludos.

Título: Re: Concurso de programación: números romanos
Publicado por: Nocturno en 17 de Junio de 2013, 14:48:32
Ya están publicados los resultados del concurso. Podéis verlos aquí.
http://www.micropic.es/mpblog/2013/06/resultados-primer-concurso-de-programacion-numeros-romanos/

Enhorabuena al ganador.