| Ver tema anterior :: Ver siguiente tema | | Autor | Mensaje |
|---|
edmec2000
Registrado: 15 Abr 2014 Mensajes: 2
| Publicado: 15/04/2014 6:59 am | | | Título: Ayuda Numero M-Alternante |
| Buenos días compañeros,
Tengo un problema quiero solicitar su valiosa ayuda. (solo busco un tip, idea que me pueda ayudar a resolver el problema)
El problema es el siguiente:
Un número entero positivo se dice M-alternante si : El primer dígito es par entonces los 2 dígitos siguientes deben ser impares, luego los tres siguientes dígitos deben ser pares y así sucesivamente.
Por ejemplo: 122357 es un número M-alternante de orden 3 Lo que no encuentro como hacer es para ir comparando si el primero es par, y luego los siguientes 2 de la cadena sean impares y luego los siguientes 3 de la cadena sean impares.
he ingresado el numero en un string, para ir manipulando cada caracter por separado (Claro haciendo las conversiones necesarias). y verificar con mod (%) si es par o impar.
Pero lo que se me esta complicando es el procedimiento que vaya alternando 1 primero par, luego los siguientes 2 impares, luego los siguientes 3 pares, luego siguientes 4 impares, asi sucesivamente.
1 par siguientes 2 posiciones impares siguientes 3 posiciones pares siguientes 4 posiciones impares siguientes 5 posiciones pares asi sucesivamente para Numeros de N posiciones.
Les agradezco mucho cualquier tip que me puedan dar, |
| | Volver arriba | |  | vangodp
Registrado: 25 Ene 2014 Mensajes: 30
| Publicado: 15/04/2014 7:08 pm | | | Título: |
| Creo que para eso deberías desglosarlo. Por ejemplo para saber si el primero de los números 122357 "el uno" es par o impar pues divides el 122357 por 100000 que te va dejar el primer numero "SOLO" lo cual ya puedes hacerle comprobaciones.
Si tenemos ahora 22357 pues ahora le dividimos por 10000 y nos va dejar con el siguiente que es 2, después por 2357 / 1000 , 375/100, 75/10 y y ya el ultimo no hace falta XDD
para saber si es par o impar pues se usa una variable temporal para ir guardando el valor de las divisiones anteriores y ir comparando mas o menos así: if( temp % 2 == 0 ){ cout << "Es par"; }else{ cout << "Es impar"; }
bueno espero que te sirva 
 |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 7516 Ubicación: Mexico
| Publicado: 15/04/2014 9:40 pm | | | Título: |
| | edmec2000 escribió: | | lo que se me esta complicando es el procedimiento que vaya alternando 1 primero par, luego los siguientes 2 impares, luego los siguientes 3 pares, luego siguientes 4 impares, asi sucesivamente. |
Basta con tres variables: una para procesar cada dígito, otra para contar el numero de dígitos pares o impares en secuencia y la ultima para el numero de dígitos en secuencia requeridos (un impar, dos pares, tres impares, etc.).
Por ejemplo:
| Código: | #include <stdio.h> #include <stdlib.h>
int fn(int digit[], int num_digits);
int main(void) { int digit[] = {1, 2, 2, 3, 5, 7}; int num_digits = (int) (sizeof digit / sizeof digit[0]); printf("%d\n", fn(digit, num_digits)); return EXIT_SUCCESS; }
int fn(int digit[], int num_digits) { int i; int j = 0; int reqs = 1; for (i = 0; i < num_digits && digit[i] % 2 == reqs % 2; i++) if (++j == reqs){ j = 0; reqs++; } return i == num_digits && j == 0; } |
Un saludo _________________ C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language |
| | Volver arriba | |  | | leosan
Registrado: 19 Abr 2012 Mensajes: 730 Ubicación: GRAN CANARIA
| Publicado: 16/04/2014 7:04 am | | | Título: |
| | rir3760 escribió: | Basta con tres variables: una para procesar cada dígito, otra para contar el numero de dígitos pares o impares en secuencia y la ultima para el numero de dígitos en secuencia requeridos (un impar, dos pares, tres impares, etc.). ...........................
|
Que te voy a contar amigo rir3760, como siempre me has dejado con la boca abierta, yo con mi artillería matemática y tú con una" j" rompedora. Sólo un pero, no tiene en cuenta que la secuencia puede ser impar, par, impar.... o par, impar, par ..... pero vamos, es una minucia de nada.
No me resisto a poner mis dos opciones, la primera con una variable más que tu código pero, como he comentado, más matemático y la segunda con una función recursiva:
* parto de lo que el autor expresa, toma el número como un char y luego lo paso a int obteniendo en este primer paso el número de elementos que componen el número.
* para empezar he implementado de entrada el que pueda ser M-Alternate según el número de cifras que compongan el número, ya que estas han de coincidir con la suma de los números naturales.
* cumpliéndose esta condición, obtengo el número "n" de grupos de cifras que componen el número.
* uso la variable "p_i" para ir viendo si cada grupo es par o impar o al revés.
* recorro en en el for de j los grupos de cifras comprobando si cumplen con la condición par-impar.
| Código: | #include <stdio.h> #include <stdlib.h> #include <string.h>
int main(){ int i,j,k=1,n,p_i=0,flag=0; char numero[]={/*"124357682431597246282"*/"235468315762864135795"}; int lon=strlen (numero); int num[lon]; for (i=1;i<lon;i++) if (i*(i+1)==2*lon){ puts("\n\tPor el numero de cifras puede ser M-Alternante"); n=i; flag=1; } if (flag==0){ puts ("\n\tPor el numero de cifras No es M-Alternante\n"); exit(1); } for (i=0;i<lon;i++) num[i]=numero[i]-'0'; if (num[0]%2==0) p_i=0; else p_i=1; for(i=0;i<n;i++){ for (j=i*(i+1)/2;j<=i*(i+1)/2+i;j++){ printf("\nnum[%d]=%d p_i=%d\n",j,num[j],p_i); if (num[j]%2!=p_i){ puts ("\n\tNo es M-Alternante\n"); exit(3); } } if (p_i==0) p_i=1; else /*if (p_i==1)*/ p_i=0; putchar ('\n');system ("pause"); } puts ("\n\t\tES M-Alternante\n"); return 0; } |
Y la ya comentada con función recursiva:
| Código: | #include <stdio.h> #include <stdlib.h> #include <string.h>
void numeros(int *num, int i, int p_i, int lon);
int main(){ int i,k=1,p_i,flag=0; char numero[]={"124357682431597246282"/*"235468315762864135795"*/}; int lon=strlen (numero); int num[lon]; for (i=1;i<lon;i++) if (i*(i+1)==2*lon){ puts("\n\tPor el numero de cifras puede ser M-Alternante"); flag=1; } if (flag==0){ puts ("\n\tPor el numero de cifras No es M-Alternante\n"); exit(1); } for (i=0;i<lon;i++) num[i]=numero[i]-'0'; if (num[0]%2==0) p_i=0; else p_i=1; i=0; numeros (num,i,p_i,lon); return 0; }
void numeros(int num[], int i, int p_i, int lon){ int j; if (i*(i+1)/2==lon){ puts ("\n\t\tES M-Alternante\n"); exit(2); } system("pause"); for (j=i*(i+1)/2;j<=i*(i+1)/2+i;j++){ printf("\nnum[%d]=%d p_i=%d\n",j,num[j],p_i); if (num[j]%2!=p_i){ puts ("\n\tNo es M-Alternante\n"); exit(3); } } if (p_i==0) p_i=1; else /*if (p_i==1)*/ p_i=0; numeros (num,i+1,p_i,lon); } |
Dejo en ambos casos un printf para que se entienda mejor lo que va haciendo el código y dos casos de M-Alternate.
Y repito por e.nésima vez, gracias rir por tus enseñanzas, jamás se me habría ocurrido una manera tan ingeniosa. Una vez vista parece sencillo y uno se prgunta ¡cómo no se me ocurrió!. pero es que tus códigos son ....digamos que "especiales".
Saluditos!.
EDITO: Y como aquí estamos para lo que estamos, para aprender de los maestros como rir3760 , mi propuesta sin tantas matemáticas pero considerando los dos casos, que empiece por impar o por par, y lanzando mensajes de si es o no M-Alternante:
| Código: | #include <stdio.h> #include <stdlib.h> #include <string.h>
int main(){ int i,j,k=1,n,p_i=0,flag=0; char numero[]={/*"124357682431597246282"*/"235468315762864135795"}; int lon=strlen (numero); int num[lon]; ///printf("\nlon=%d\n",lon); for (i=1;i<lon;i++) if (i*(i+1)==2*lon){ puts("\n\tPor el numero de cifras puede ser M-Alternante"); n=i; printf("\nn=%d\n",n); flag=1; } if (flag==0){ puts ("\n\tPor el numero de cifras No es M-Alternante\n"); exit(1); } for (i=0;i<lon;i++) num[i]=numero[i]-'0'; if (num[0]%2==0) p_i=flag=0; else p_i=flag=1; i=0; for (j=0;j<lon;j++){ ///printf("\nnum[%d]=%d p_i=%d i=%d\n",j,num[j],p_i,i); if (num[j]%2!=(p_i%2)){ puts ("\n\tNo es M-Alternante\n"); exit(3); } if ((flag==1 && ++i==p_i) || (flag==0 && i++==p_i)){ p_i++; i=0; } }putchar ('\n');///system ("pause"); puts ("\n\t\tES M-Alternante\n"); return 0; } |
|
| | Volver arriba | |  | edmec2000
Registrado: 15 Abr 2014 Mensajes: 2
| Publicado: 16/04/2014 5:43 pm | | | Título: |
| Gracias Compañeros,
Son unos genios!!!
Saludos, |
| | Volver arriba | |  | Pantalàimon_
Registrado: 17 Jul 2007 Mensajes: 1344
| Publicado: 17/04/2014 9:19 am | | | Título: |
| Estoy un poco oxidado pero aquí va mi versión recursiva usando la nomenclatura de rir3760:
| Código: | #include <stdio.h> #include <stdlib.h> #include <math.h>
int fn(int digit[], int num_digits); int fn_rec( int digit[], int num_digits, int n, int parity );
int main(void) { int digit[] = {2, 5, 3, 6, 0, 8}; int num_digits = (int) (sizeof digit / sizeof digit[0]); printf("%d\n", fn(digit, num_digits)); return EXIT_SUCCESS; }
int fn(int digit[], int num_digits) { int reqs = 0.5 * sqrt( 1 + 8 * num_digits ); if( reqs*(reqs+1) != 2 * num_digits ) return 0; else return fn_rec( digit, num_digits, reqs, digit[num_digits-1] % 2 ); }
int fn_rec( int digit[], int num_digits, int reqs, int parity ) { if( num_digits > 0 ) { int i; for( i = 1; i <= reqs && digit[num_digits - i] % 2 == parity; ++i ) ; return i > reqs && fn_rec( digit, num_digits - reqs, reqs-1, !parity ); } return 1; } |
| leosan escribió: | | gracias rir por tus enseñanzas, [...] pero es que tus códigos son ....digamos que "especiales". |
Yo te diré porque son especiales: porque demuestran que hacer un código corto y escatimar espacios no van parejos 
| leosan escribió: | | Sólo un pero, no tiene en cuenta que la secuencia puede ser impar, par, impar.... o par, impar, par |
Es que el autor del hilo no lo explicó demasiado bien. Aquí una definición que he encontrado por internet:
| Cita: | Un número entero positivo se dice M-alternante si : El primer dígito es par (impar) entonces los 2 dígitos siguientes deben ser impares (pares), luego los tres siguientes dígitos deben ser pares (impares) y así sucesivamente. |
De manera que con unos pequeños cambios ya estaría hecha:
| Código: | int fn(int digit[], int num_digits) { int i; int j = 0; int reqs = 1; int parity = digit[0] % 2; for (i = 0; i < num_digits && (digit[i] % 2 ^ reqs % 2) != parity; i++) if (++j == reqs){ j = 0; reqs++; } return i == num_digits && j == 0; } |
Un saludo! |
| | Volver arriba | |  | | leosan
Registrado: 19 Abr 2012 Mensajes: 730 Ubicación: GRAN CANARIA
| Publicado: 24/04/2014 9:37 am | | | Título: |
| | Pantalàimon_ escribió: | Estoy un poco oxidado pero aquí va mi versión recursiva usando la nomenclatura de rir3760: ......................................
| leosan escribió: | | gracias rir por tus enseñanzas, [...] pero es que tus códigos son ....digamos que "especiales". |
Yo te diré porque son especiales: porque demuestran que hacer un código corto y escatimar espacios no van parejos  .................................................... Un saludo! |
Antes que nada, un fuerte saludo Pantalàimon_ y decirte que estoy emocionado por volver a encontrarte en el foro.
Ya quisiera yo tener el óxido que según tu tienes. 
Lo de los espacios es cuestión de haberme acostumbrado al usar una mini-ventana para los códigos, si pongo muchos no me caben. Sí, ya lo sé, usar una ventana mayor, pero es que ya me he acostumbrado. Y no, no es por eso, es que suelen plantear puntos de vista cuanto menos originales, rompedores para mi. Y no tiene nada que ver con que sean cortitos o no.
Pero vamos al meollo del tema.
Si de lo que se trata es de que el código emita un criptico mensaje, tipo:
ó:
para indicar si es o no M-Alterrnate, re-propongo un código con función recursiva:
| Código: | #include <stdio.h>
int numeros(int *num, int i, int par_imp, int lon){ int j, k=i*(i+1)/2; for ( j=k; j<=k+i && ((num[j]%2)==par_imp); j++); return ((j-1==k+i) && numeros ( num, ++i, !par_imp, lon) || ((k == lon ) && 1) ); }
int main(void){ int i=0,num[]={1,2,4,3,5,7,6,8,0,4,3,1,5,3,7,2,4,0,8,6,2/*2,3,5,4,6,8,3,1,5,7,6,2,8,6,4*/}; int lon=sizeof num/sizeof *num; return printf("\n\"%d\"\n",numeros (num, i, num[0]%2, lon)) && 1; } |
Aunque ya sabes lo que me gusta a mi un printf. Yo prefiero que se aporte mayor información al usuario, algo como:
| Cita: |
Introduzca un numero de 80 digitos maximo:
1243574
Por el numero de cifras 7 != ( 6 o 10 ) No es M-Alternante
|
| Cita: |
Introduzca un numero de 80 digitos maximo:
124357248613579248606
Por el numero de cifras puede ser M-Alternante
1 24 357 2486 13579 248606 ES M-Alternante
|
Y como se intuye no voy buscando un código cortito, que también, sino un código que aporte más información a su ejecución, para lo cual he tenido en cuenta lo que el autor del tema proponía acerca de que el número se introdujera como una cadena, lo que no limita el número de dígitos, y además he hecho uso de una segunda cadena para presentar al final el número con sus cifras separadas, como se observa en la anterior salida. Y para variar éste no es recursivo:
| Código: | #include <stdio.h> #include <math.h> #define MAX 80
int main(){ int i=0, j, k=0, l=0, p_i=0, flag=0, digits=0; char numero[MAX+1]; do{ printf ("\n\tIntroduzca un numero de %d digitos maximo:\n\n",MAX); scanf ("%s",numero); for (digits=0;numero[digits];digits++) if (numero[digits]<'0' || numero[digits]>'9'){ digits=MAX+1; break; } }while (digits>MAX); j =(-1+sqrt(1+8*digits))/2; if ( j*(j+1) != 2*digits ) return printf( "\n\tPor el numero de cifras %d != ( %d o %d ) No es M-Alternante\n",digits,j*(j+1)/2,(j+1)*(j+2)/2 ) && 0;puts("\n\tPor el numero de cifras puede ser M-Alternante" ); char numero1[digits+1+j]; flag = p_i = (numero[0]-'0')%2; for ( j = 0 ; j< digits ; j++ ){ ///printf("\nnum[%d]=%d p_i=%d i=%d\n",j,num[j],p_i,i); numero1[k++] = numero[j]; if ((numero[j]-'0')%2!=(p_i%2)){ numero1[k] = '\0'; return printf ( "\n\t\t%s\n\n\t%s No es M-Alternante\n", numero,numero1 ) && 0 ; } if ( i++ == p_i - flag ) numero1[k++]=' ', p_i++, i=0; } numero1[k]='\0'; return printf ( "\n\t%s ES M-Alternante\n", numero1 ) && 0; } |
Sí, sí, ya lo sé, los return son raritos pero es que estoy haciendo "probaturas". 
Saluditos!.
P.D: Sí, ya sé que el -1 que pongo delante de sqrt podía haberlo deshechado por ser la división entera, pero es por si alguien se molesta en resolver la ecuación j*(j+1)/2=digits no piense que me he olvidado de resolver ecuaciones de segundo grado.  |
| | Volver arriba | |  | Pantalàimon_
Registrado: 17 Jul 2007 Mensajes: 1344
| Publicado: 25/04/2014 4:32 pm | | | Título: |
| | leosan escribió: | | P.D: Sí, ya sé que el -1 que pongo delante de sqrt podía haberlo deshechado por ser la división entera, pero es por si alguien se molesta en resolver la ecuación j*(j+1)/2=digits no piense que me he olvidado de resolver ecuaciones de segundo grado. |
Lo dices por poner algo del estilo:
| Código: | j =(-1+sqrt(1+8*digits))/2; |
donde yo puse
| Código: | int reqs = 0.5 * sqrt( 1 + 8 * num_digits ); |
¿No?
Yo realmente quería poner algo del estilo:
| Código: | int reqs = round( 0.5 *( -1 + sqrt( 1 + 8 * num_digits ) ) ); |
Pues al hacer, por ejemplo, sqrt(9) no estaba seguro de si alguna vez me saldría de resultado 2.999999 o 3.000001 dependiendo de la representación binaria de los números reales. Con lo cual me parecía más seguro hacer un redondeo hacia el número más próximo para asegurarme de no encontrarme algún resultado extraño con el truncamiento.
Lo que después pensando un poco llegue a la conclusion que round( x ) == floor( x + 0.5 ). Con lo cual estas sentencias son equivalentes:
| Código: | int reqs = round( 0.5 *( -1 + sqrt( 1 + 8 * num_digits ) ) ); int reqs = floor( 0.5 + 0.5 *( -1 + sqrt( 1 + 8 * num_digits ) ) ); int reqs = 0.5 + 0.5 *( -1 + sqrt( 1 + 8 * num_digits ) ); int reqs = 0.5 *( 1 -1 + sqrt( 1 + 8 * num_digits ) ); int reqs = 0.5 * sqrt( 1 + 8 * num_digits );
|
Así que puse lo último para ir de programador más molón.
Sobre lo de los espacios y tal, no te preocupes. Es alguno de estos azotes sarcásticos que me gusta dar de vez en cuando. No te lo tomes a pecho.
Un abrazo! |
| | Volver arriba | |  | | |
| No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas
|
|
| |