[C con Clase] Como hago para unir dos codigos?

José Luis Torre joseluistorrehernandez en gmail.com
Mar Sep 18 12:39:23 CEST 2012


Hola Ali:

He preparado un ejercicio para que veas cómo se pueden hacer las cosas
de múltiples formas, pero lo que creo que es más importante es que las
instrucciones deben ser lo más sencillas posibles y utilizando los
mejores algoritmos.

Cuando no conocemos un algoritmo, las cosas también se pueden hacer a
base de cálculos, pero siempre teniendo en cuenta que lo hacemos para
salir del paso y cuando dicha función no se tenga que ejecutar
demasiadas veces.

Por otro lado, desconozco tu nivel de conocimientos de C, así que
supondré que todavía no conoces los arrays y por lo tanto no los
utilizaré.

El ejercicio consiste en obtener de forma explícita las permutaciones
de n cifras variando n de 1 hasta 9.

Espero que te sirva.

El código es el siguiente:

// Veamos una forma compacta y simple (en código)
// de obtener explicitamente todas  las formss
// de ordenar n cifras  (sin repetición)
// N puede variar desde 1 hasta 6.
// Se excluye el 0.
// No se usan arrays.

#include <stdio.h>

#define N 5

void separar(int n);
int sumaGaus(int n);
int factorial(int n);
int unicos(int n, int u, int d, int c, int um, int dm, int cm);
int productoCifrasSignificativas(int u, int d, int c, int um, int dm, int cm);
int numcifras(int u, int d, int c, int um, int dm, int cm);


void separar(int n)
{
     int max; // máximo valor a probar
     int i;
     int u;       // unidades
     int d;       // decenas
     int c;       // centenas
     int um;      // unidades de mil
     int dm;      // decenas de mil
     int cm;      // centenas de mil
     int f = 0;   // fila

     max = (int) pow(10, n);
     for (i = 1; i < max; ++i)
     {
         u = i % 10;
         d = (i/10)%10;
         c = (i/100)%10;
         um = (i/1000)%10;
         dm = (i/10000)%10;
         cm = (i/100000)%10;

         if (unicos(n, u, d, c, um, dm, cm)) // printf("%5d %6d %d %d
%d %d %d %d\n", f, i, cm, dm, um, c, d, u);
         {
            printf("%5d %6d %d %d %d %d %d %d\n", f, i, cm, dm, um, c, d, u);
            ++f;
         }
     }
}
int sumaGaus(int n)
{
    return (1+n)*n/2;
}

int factorial(int n)
{
    if (n==1)
       return 1;
    else
       return n*factorial(n-1);
}

int unicos(int n, int u, int d, int c, int um, int dm, int cm)
{
    const double epsilon = 0.001;
    int suma;
    int prod;
    int sn; // suma de los n primeros naturales
    int pn; // producto de los n primeros naturales
    int nc; // número de cifras significativas

    if (n > 6) return 0;

    // sumar los números del 1 al n
    sn = sumaGaus(n);
    pn = factorial(n);
    nc = numcifras(u, d, c, um, dm, cm);

    // multiplicar los números del 1 al n

    suma = u + d + c + um + dm + cm;
    prod = productoCifrasSignificativas(u, d, c, um, dm, cm);

    // printf("la suma es %d y debe ser %d\n", suma, sn);
    // printf("el producto es %d y debe ser %d\n", prod, pn);

    if (fabs(suma - sn) > epsilon) return 0;
    if (fabs(prod - pn) > epsilon) return 0;
    if (n != nc) return 0;

    // conjetura: confío en que sirvan las pruebas anteriores...
    return 1;
}
int productoCifrasSignificativas(int u, int d, int c, int um, int dm, int cm)
{
    if (cm) return cm*dm*um*c*d*u;
    if (dm) return dm*um*c*d*u;
    if (um) return um*c*d*u;
    if (c)  return c*d*u;
    if (d)  return d*u;
    if (u)  return u;
    return 0;
}
int numcifras(int u, int d, int c, int um, int dm, int cm)
{
    if (cm) return 6;
    if (dm) return 5;
    if (um) return 4;
    if (c)  return 3;
    if (d)  return 2;
    if (u)  return 1;
    return 0;
}
int main(void)
{
    separar(N);
    system("pause");
}


El día 17 de septiembre de 2012 02:56, Ali Rincon
<alrincon1963 en hotmail.com> escribió:
> El pasado 2012-09-16 18:13:08, jiptohej escribió:
>
> j> Hola Ali:
> j> A continuación te muestro el programa principal, en el que puedes ver
> j> que he introducido una nueva función:
> j> int main(void)
> j> {
> j>     int N, k;
> j>     printf("Introduzca el valor de N: ");
> j>     scanf("%d", &N);
> j>     printf("Introduzca el valor de k: ");
> j>     scanf("%d", &k);
> j>     implicitas(N, k);
> j>     system("pause");
> j> }
> j> Como puedes ver la nueva función se denomina implicitas() y es
> j> prácticamente igual al código que tu utilizas, si más que eliminar las
> j> variables N y k que pasan a ser parámetros de la función.
> j> Como puedes ver, de este modo tan sencillo es como se simplifican los
> j> programas. Ten siempre en cuenta que los programas deben ser lo más
> j> sencillos que sea posible.
> j> A continuación te muestro la función quitando las instrucciones que ya
> j> conoces (porque las has escrito tu)
> j> void implicitas(int N, int k)
> j> {
> j>     int i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15;
> j>     if (k == 2)
> j>     {
> j>         for (i1 = 1; i1 <= N; i1++)
> j>         {
> j>             for (i2 = i1 + 1; i2 <= N; i2++)
> j>             if (i1 != i2)
> j>             printf("[%d %d]\t", i1, i2);
> j>         }
> j>     }
> j>     else
> j>     {
> j>         if (k == 3)
> j>  ...
> j> }
> j> Por otro lado te comento, creo que como ejercicio puede servirte para
> j> aprender, pero tienes que darte cuenta de que tiene que haber un
> j> método mucho más sencillo para resolverlo.
>
> Muchisimas gracias, por tu amable respuesta, jiptohej. En efecto debe de haber una forma mas elegante, como tu la sugieres, de hacer la segunda parte del codigo que hice. Pero te confieso que no tengo ninguna idea al respecto. Tu me sugieres que defina una funcion que realice los calculos de la segunda parte, y que la llame al finalizar la primera parte, de manera de hacer el programa mas sencillo. Asi interpreto tu sugerencia. Como soy nuevo en C, las combinaciones de la segunda parte las hice a "fuerza bruta", y salen. Me gustaria saber si conoces alguna manera, más explicita, de generalizar el segundo codigo. No se como "generalizar" los bucles de for. Te comento que en este instante, en que te estoy escribiendo, un amigo me indicó un error en el segundo codigo y es que la proposicion scanf en la linea 55 no debe ir con %c sino con %s pues es una cadena de caracteres donde se asigna. Con esta indicacion, introduje las siguientes sentencias despues de la finalizacion del bucle de do...while:
>     printf("\nDesea ver estas combinaciones de manera explicita (s/n)?: ");
>     scanf("%s", &siga);
>     if(siga != 'n')
>     {
>      ...
>     }
> y me corre el programa hermosamente, con los dos codigos juntos en un mismo programa. Ahora, deseo perfeccionar este codigo, como tu me lo sugieres. Pero si puedes, dame una indicacion mas explicita, por favor, si tienes tiempo y esta a tu alcance.
>
> Muchisimas gracias nuevamente, por la atencion prestada.
>
> Muy atentamente,
>
> Ali
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ



-- 
José Luis Torre
ww.ehu.es




Más información sobre la lista de distribución Cconclase