Autor Tema: Número capicúa

0 Usuarios y 1 Visitante están viendo este tema.

13 Mayo, 2015, 07:48 pm
Leído 3871 veces

Estudiantee

  • Aprendiz
  • Mensajes: 423
  • Karma: +0/-0
  • Sexo: Masculino
me piden que haga una función para un número capicua.
Yo hago esto pero no sé seguir. Una ayuda? Es en C
#include<stdio.h>
#include<stdlib.h>
int main(void){
int n;
printf("Dime el numero\n");
scanf("%d",&n);
while(n<0){
    printf("Dime el numero\n");
scanf("%d",&n);

}
int k;
k=0;
while(n>=1){
    n=n/10;
    k=k+1;
}printf("numero de cifras: %d\n",k);
Si alguien me invita a forocoches, se lo agradecería.

14 Mayo, 2015, 12:38 am
Respuesta #1

ingmarov

  • Moderador Global
  • Mensajes: 4,702
  • País: hn
  • Karma: +0/-0
  • Sexo: Masculino
Hola

Y, ¿no te dieron más especificaciones?

¿Cuál es tu idea?


Ya entiendo que intentas hacer, lo pensaré y luego editaré este mensaje.
No te confíes, revisa lo que escribo. Yo también me equivoco.
Odio el autocorrector de Android...

14 Mayo, 2015, 02:27 am
Respuesta #2

ingmarov

  • Moderador Global
  • Mensajes: 4,702
  • País: hn
  • Karma: +0/-0
  • Sexo: Masculino
Para encontrar las cifras del número puedes usar la función módulo.

por ejemplo el número 357

357%10=7   

357-357%10=350

350%100=50

350-350%100=300

300%1000=300

Con eso creo que puedes descomponer en cifras cualquier número y generar el capicua que deseas.

Dentro del spoiler he probado lo anterior en python y funciona bien. Quizás lo puedas entender y lo exportes a C.

Spoiler
>>> def capicua():
   num=int(input("Ingrese un Número entero: "))
   i,res,l,m,f=0,-1,num,[],-1
   while f==-1:
      res=l%10**(i+1)
      if res!=l:
         m.append(int(res/(10**i)))
         l=l-res
      else:
         m.append(int(res/(10**i)))
         f=0
      i=i+1
   print(m)

   
>>> capicua()              #Esta es la llamada a la función capicua.
Ingrese un Número entero: 123456
[6, 5, 4, 3, 2, 1]            #Esta es la salida mostrando las cifras invertidas del número ingresado.

[cerrar]



Finalmente el programa terminado dentro del spoiler. (Pero en python)

Spoiler
>>> def capicua():
   num=int(input("Ingrese un Número entero: "))
   i,res,l,m,f=0,-1,num,[],-1
   while f==-1:
      res=l%10**(i+1)
      if res!=l:
         m.append(int(res/(10**i)))
         l=l-res
      else:
         m.append(int(res/(10**i)))
         f=0
      i=i+1
   num=num*10**(len(m))
   for i in range(len(m)):
      num=num+m*(10**(len(m)-1-i))
   return num



>>> capicua()
Ingrese un Número entero: 12345
1234554321
[cerrar]
No te confíes, revisa lo que escribo. Yo también me equivoco.
Odio el autocorrector de Android...

16 Mayo, 2015, 05:27 pm
Respuesta #3

Estudiantee

  • Aprendiz
  • Mensajes: 423
  • Karma: +0/-0
  • Sexo: Masculino
No lo entiendo, se me da horrible programar :-[
Si alguien me invita a forocoches, se lo agradecería.

16 Mayo, 2015, 05:31 pm
Respuesta #4

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,292
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
  • Vean mis posts activos en mi página personal
    • Mis posts activos (click aquí)
Para poder programar hace falta que el enunciado del problema sea preciso.
De hecho, esa es la parte más importante de un programa.

ingmarov está adivinando lo que tienes que hacer,
pero yo todavía no entiendo qué es lo que te piden.

16 Mayo, 2015, 05:44 pm
Respuesta #5

Estudiantee

  • Aprendiz
  • Mensajes: 423
  • Karma: +0/-0
  • Sexo: Masculino
Me pide que haga un programa que al introducir un numero me diga si es capicua o no.
Lo que he pensado es separar sus cifras y comparar la primera con la ultima y asi sucesivamente. Si coinciden sera capicua
Si alguien me invita a forocoches, se lo agradecería.

16 Mayo, 2015, 06:52 pm
Respuesta #6

Juan Pablo Sancho

  • Moderador Global
  • Mensajes: 4,761
  • País: es
  • Karma: +0/-0
  • Sexo: Masculino
Propongo este desastre:(hace mucho tiempo que no toco esto del c).

Spoiler
#include<stdio.h>
#include<stdlib.h>

int main(void)

{
int cifra[1000],i=0,j,l=0;

printf("Dame un número entero positivo cifra a cifra\n");
printf("Al terminar de poner la cifra pon -1\n");


do
{
 
  scanf("%d",&cifra);  debería salir "cifra\(  [i]  \).
  i++;
 
}while(cifra[i-1] != -1); 



i = i-1;


printf("%d\n",i);

for(j = 0 ; j < i/2 ; j++)
{
   
if(cifra[j] != cifra[i-1-j])
  l = 1;
}

if(l==1)
printf("No es capicua");
else
printf("Es capicua");

return(0);


[cerrar]
Ingmarov y argentinator cuando lo veáis no lloréis mucho  ;D ;D (tengais benevolencia).

16 Mayo, 2015, 07:00 pm
Respuesta #7

ingmarov

  • Moderador Global
  • Mensajes: 4,702
  • País: hn
  • Karma: +0/-0
  • Sexo: Masculino
Hola

...

ingmarov está adivinando lo que tienes que hacer,
...

Totalmente cierto.  :P

El consuelo que me queda es que gané experiecia. :D :D :D.

El programa que publiqué, separa las cifras del número introducido y construye un número Capicuá con estas cifras, este número resultante comienza con el número original y termina con su "reflexión".

Me pide que haga un programa que al introducir un numero me diga si es capicua o no.
Lo que he pensado es separar sus cifras y comparar la primera con la ultima y asi sucesivamente. Si coinciden sera capicua

La parte del programa que separa las cifras del núero es:

Lo simplifico un poco y lo comento para que lo entiendas más fácil.

i=0
res=-1
l=num  #num es el número introducido.
m=[]   #Esto es una lista (arreglo) vacío, sirve para almacenar las cifras del número introducido.
f=-1
   while f==-1:
      res=l%10**(i+1) #Esto se traduce como l%pow(10,i+1) es decir, calcula el módulo (resto o residuo) de l(num) y potencias de 10, Ej. 123%pow(10,1)=123%10=3
      if res!=l:              #Si res es diferente de l ("ele" no 1 perdón por eso ). Cuando res=l pasa al bloque "else" y termina el ciclo while. Ej. 123%pow(10,3)=0
         m.append(int(res/(10**i)))   #Arega al arreglo m el resto o residuo dividido entre potencia de 10 que lo convierte a unidades. 20/10=2
         l=l-res    #Le resta el actual residuo para que el siguiente res no lo incluya.
      else:
         m.append(int(res/(10**i)))  #Agrega la última cifra al arreglo m.
         f=0   #Con esto termina el ciclo while
      i=i+1  #Esto es para cambiar los exponentes de las potencias de 10.


Espero te sirva ahora.


Propongo este desastre:(hace mucho tiempo que no toco esto del c).

Spoiler
#include<stdio.h>
#include<stdlib.h>

int main(void)

{
int cifra[1000],i=0,j,l=0;

printf("Dame un número entero positivo cifra a cifra\n");
printf("Al terminar de poner la cifra pon -1\n");


do
{
 
  scanf("%d",&cifra);  debería salir "cifra\(  [i]  \).
  i++;
 
}while(cifra[i-1] != -1); 



i = i-1;


printf("%d\n",i);

for(j = 0 ; j < i/2 ; j++)
{
   
if(cifra[j] != cifra[i-1-j])
  l = 1;
}

if(l==1)
printf("No es capicua");
else
printf("Es capicua");

return(0);


[cerrar]
Ingmarov y argentinator cuando lo veáis no lloréis mucho  ;D ;D (tengais benevolencia).


A mí me parece una buena idea. Ha de funcionar muy bien.


Y me parece prácico definir un arreglo de 1000 elementos, porque si me dan un número de mil cifras, a mano (a simple vista) sería difícil decir si es capicuá o no; aunque será mucho trabajo introducir 1000 cifras. Si me dan un número de 20 cifras es fácil decir a simple vista si es capicuá y no necesito programa. ;D
No te confíes, revisa lo que escribo. Yo también me equivoco.
Odio el autocorrector de Android...

16 Mayo, 2015, 09:33 pm
Respuesta #8

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,292
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
  • Vean mis posts activos en mi página personal
    • Mis posts activos (click aquí)
Bueno, todo depende de cómo se ingresa el número.

Si el número se ingresa como un dato de tipo int, entonces tendrá un número acotado de cifras, dado por la implementación (el compilador),
cuyo tamaño puede saberse a ciencia cierta consultando los valores de la librería limits.h.
Entonces no haría falta un array de 1000 cifras.

Para el caso de enteros de 32 bits, daría valores del orden de los 2000 millones, así que un array de 10 cifras bastaría.

El tipo de datos más grande que existe en C, para números enteros positivos, es uintmax_t, que en general coincide con unsigned long long int, que contiene números del orden de \( 2^{64}\approx 1.8\times 10^{19}  \), que son unas 19 cifras.

-----------

En cualquier caso, no me parece necesario usar arrays para este problema, a menos que los datos vengan ya en forma de un array de dígitos.

Los pasos a dar serían estos:

* Calcular el número de dígitos decimales del número.
* Obtener la primera y última cifra del número y comparar. Hacer lo mismo con las siguientes hasta llegar al centro del número.

No hace falta seguir más allá de las cifras centrales, porque las cifras correspondientes ya estarían comparadas.f

Para obtener la primera cifra, basta dividir por la potencia de 10 más cercana al número.
Para obtener la última cifra, se toma el resto módulo 10.
Para obtener las siguientes cifras, habría que eliminar estas cifras primera y última, para poder aplicar el mismo método a las cifras restantes.

De hecho, una propiedad invariante de un número capicúa es que, si quitamos la primera y la última cifra, el número que queda es también capicúa.
Pero, más importante, si las primera y última cifra coinciden, y si al quitarlas lo que queda es capicúa, es que el número original era capicúa.
Ejemplo:

17871

La primera y última cifra son iguales a 1, y al quitarlas nos queda el número capicúa 787.
Esto implica que el número original 17871 era ya capicúa.

Con esta propiedad invariante, podemos pensar un algoritmo, así:


/* CAPICUA

   Entrada: Un número entero n
   Salida:  Informar si el número n es capicúa o no.
   Método:  Iteraciones, sin almacenar las cifras en memoria adicional.
*/

#include <math.h>
#include <stdio.h>

int main(void)
{
  int n;
  printf("Ingrese un numero entero: ");
  scanf("%d", &n);

  /* Por defecto, asumiremos que el número es capicua,
     a menos que se detecte lo contrario.
     La variable capicua será 1 (verdadero) mientras
     "todavía no se haya detectado que n no es capicua".
     Si al final del proceso sigue siendo 1,
     es que n efectivamente era capicúa.
  */

  int capicua = 1;

  int digitos = log10(n) + 1;
  int pow10 = round(pow(10, digitos-1)); /* Potencia de 10 inferior más cercana a n */
  int nn = n; /* Copiamos n en nn para modificarlo sin perder valor original */
  while (pow10 > 0)
  {
    /* capicua == 1: El número nn todavía no se ha detectado como no-capicúa */

    int primer_cifra = nn / pow10;
    int ultima_cifra = nn % 10;

    if (primer_cifra != ultima_cifra) /* Se detecta que nn no es capicúa */
    {
      capicua = 0; /* Valor falso */
      break;       /* Fin del proceso, no hay nada más que verificar */
    }
    /* En este punto vale la condición primer_cifra == ultima_cifra */

    /* A continuación, quitamos la primer y última cifra, achicando nn */
    nn -= primer_cifra * pow10;
    nn /= 10;   /* La división entera por 10 quita la última cifra */
    /* INVARIANTE del proceso:
          n es capicua si y sólo si primer_cifra == ultima_cifra y nn es capicúa
    */

    /* Como hemos quitado dos cifras, la potencia de 10 más cercana
       del siguiente valor de nn será pow10 / 100
    */
    pow10 /= 100;
  }

  printf("El numero %d %s capicua", n, capicua? "es": "no es");
  return 0;
}



17 Mayo, 2015, 03:33 am
Respuesta #9

ingmarov

  • Moderador Global
  • Mensajes: 4,702
  • País: hn
  • Karma: +0/-0
  • Sexo: Masculino
Genial! Es bueno leer códigos distintos para resolver un problema, se aprende mucho.

Spoiler
Bueno, todo depende de cómo se ingresa el número.

Si el número se ingresa como un dato de tipo int, entonces tendrá un número acotado de cifras, dado por la implementación (el compilador),
cuyo tamaño puede saberse a ciencia cierta consultando los valores de la librería limits.h.
Entonces no haría falta un array de 1000 cifras.

Para el caso de enteros de 32 bits, daría valores del orden de los 2000 millones, así que un array de 10 cifras bastaría.

El tipo de datos más grande que existe en C, para números enteros positivos, es uintmax_t, que en general coincide con unsigned long long int, que contiene números del orden de \( 2^{64}\approx 1.8\times 10^{19}  \), que son unas 19 cifras.

-----------

En cualquier caso, no me parece necesario usar arrays para este problema, a menos que los datos vengan ya en forma de un array de dígitos.

Los pasos a dar serían estos:

* Calcular el número de dígitos decimales del número.
* Obtener la primera y última cifra del número y comparar. Hacer lo mismo con las siguientes hasta llegar al centro del número.

No hace falta seguir más allá de las cifras centrales, porque las cifras correspondientes ya estarían comparadas.f

Para obtener la primera cifra, basta dividir por la potencia de 10 más cercana al número.
Para obtener la última cifra, se toma el resto módulo 10.
Para obtener las siguientes cifras, habría que eliminar estas cifras primera y última, para poder aplicar el mismo método a las cifras restantes.

De hecho, una propiedad invariante de un número capicúa es que, si quitamos la primera y la última cifra, el número que queda es también capicúa.
Pero, más importante, si las primera y última cifra coinciden, y si al quitarlas lo que queda es capicúa, es que el número original era capicúa.
Ejemplo:

17871

La primera y última cifra son iguales a 1, y al quitarlas nos queda el número capicúa 787.
Esto implica que el número original 17871 era ya capicúa.

Con esta propiedad invariante, podemos pensar un algoritmo, así:


/* CAPICUA

   Entrada: Un número entero n
   Salida:  Informar si el número n es capicúa o no.
   Método:  Iteraciones, sin almacenar las cifras en memoria adicional.
*/

#include <math.h>
#include <stdio.h>

int main(void)
{
  int n;
  printf("Ingrese un numero entero: ");
  scanf("%d", &n);

  /* Por defecto, asumiremos que el número es capicua,
     a menos que se detecte lo contrario.
     La variable capicua será 1 (verdadero) mientras
     "todavía no se haya detectado que n no es capicua".
     Si al final del proceso sigue siendo 1,
     es que n efectivamente era capicúa.
  */

  int capicua = 1;

  int digitos = log10(n) + 1;
  int pow10 = round(pow(10, digitos-1)); /* Potencia de 10 inferior más cercana a n */
  int nn = n; /* Copiamos n en nn para modificarlo sin perder valor original */
  while (pow10 > 0)
  {
    /* capicua == 1: El número nn todavía no se ha detectado como no-capicúa */

    int primer_cifra = nn / pow10;
    int ultima_cifra = nn % 10;

    if (primer_cifra != ultima_cifra) /* Se detecta que nn no es capicúa */
    {
      capicua = 0; /* Valor falso */
      break;       /* Fin del proceso, no hay nada más que verificar */
    }
    /* En este punto vale la condición primer_cifra == ultima_cifra */

    /* A continuación, quitamos la primer y última cifra, achicando nn */
    nn -= primer_cifra * pow10;
    nn /= 10;   /* La división entera por 10 quita la última cifra */
    /* INVARIANTE del proceso:
          n es capicua si y sólo si primer_cifra == ultima_cifra y nn es capicúa
    */

    /* Como hemos quitado dos cifras, la potencia de 10 más cercana
       del siguiente valor de nn será pow10 / 100
    */
    pow10 /= 100;
  }

  printf("El numero %d %s capicua", n, capicua? "es": "no es");
  return 0;
}



[cerrar]

Bueno, todo depende de cómo se ingresa el número.
...



...

  int digitos = log10(n) + 1;
  int pow10 = round(pow(10, digitos-1)); /* Potencia de 10 inferior más cercana a n */
...




Perdonen mi abuso argentinator y Estudiantee, es que tengo un par de dudas (y no he sido yo quien inició el hilo).  :P

Cuando defines la variable digitos como entero y le asignas el logaritmo de base 10 de "n" más uno (generalmente un número tipo float) ¿Qué hace C? lo convierte en entero, o da un error.  Es que hace bastante tiempo no uso C y he olvidado mucho.

Y lo otro la variable "digitos" solo la utilizas una vez y cuando la utilizas le restas 1, entonces ¿al definirla no era necesario sumarle 1, o me equivoco?

Saludos amigo y gracias de antemano.
No te confíes, revisa lo que escribo. Yo también me equivoco.
Odio el autocorrector de Android...

17 Mayo, 2015, 08:44 am
Respuesta #10

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,292
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
  • Vean mis posts activos en mi página personal
    • Mis posts activos (click aquí)
Lo que hace C es convertir punto flotante a entero por truncamiento.
Para evitar efectos indeseados le apliquè un redondeo, que ahora me deja el valor correcto aunque aun en punto flotante.

La variable digitos significa la cantidad de digitos.
Si le resto 1 al momento de definirla, el programa pierde legibilidad, mientras que la eficiencia es la misma.

17 Mayo, 2015, 04:13 pm
Respuesta #11

ingmarov

  • Moderador Global
  • Mensajes: 4,702
  • País: hn
  • Karma: +0/-0
  • Sexo: Masculino
Lo que hace C es convertir punto flotante a entero por truncamiento.
Para evitar efectos indeseados le apliquè un redondeo, que ahora me deja el valor correcto aunque aun en punto flotante.

La variable digitos significa la cantidad de digitos.
Si le resto 1 al momento de definirla, el programa pierde legibilidad, mientras que la eficiencia es la misma.

Todo entendido, muchas gracias.

Sobre la segunda respuesta, ya otro forísta (luis de Uruguay) me había mencionado sobre la legibilidad, que,en programacion, no se deben hacer las cosas simplemente porque se puede, se debe garantizar que otros puedan leer el programa con la mayor facilidad. Tengo mucho que aprender.

Gracias de nuevo.
No te confíes, revisa lo que escribo. Yo también me equivoco.
Odio el autocorrector de Android...

17 Mayo, 2015, 04:17 pm
Respuesta #12

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,292
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
  • Vean mis posts activos en mi página personal
    • Mis posts activos (click aquí)
Hay que buscar un equilibrio entre legibilidad y eficiencia.
Si es muy ineficiente, hay que reformular el programa.

Además, estudiantee pidió una función que resuelva el problema, y yo hice todo adentro de main().
Habría que hacer una función llamada capicua(), que devuelva 1 ó 0 según que el número pasado como parámetro sea capicúa o no.

Para lograr esta modularidad uno tiene que pensar separadamente de entrada en poner por un lado los datos de entrada, luego el proceso o solución sin usar print() ni scanf(), y finalmente exhibir la solucion en pantalla.

17 Mayo, 2015, 04:27 pm
Respuesta #13

ingmarov

  • Moderador Global
  • Mensajes: 4,702
  • País: hn
  • Karma: +0/-0
  • Sexo: Masculino
...

Además, estudiantee pidió una función que resuelva el problema, y yo hice todo adentro de main().
Habría que hacer una función llamada capicua(), que devuelva 1 ó 0 según que el número pasado como parámetro sea capicúa o no.
...

Quizás cuando leíste el código escrito por Estudiantee, pensaste que él aun no entendía la definición de función y querías garantizar que el programa que escribes pueda ser leído y entendido por Estudiantee, y por eso pusiste todo dentro de main().
No te confíes, revisa lo que escribo. Yo también me equivoco.
Odio el autocorrector de Android...

17 Mayo, 2015, 06:01 pm
Respuesta #14

Estudiantee

  • Aprendiz
  • Mensajes: 423
  • Karma: +0/-0
  • Sexo: Masculino
Gracias a todos por vuestras respuestas ;D
Si alguien me invita a forocoches, se lo agradecería.