Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Yoel Alejandro

#131
Sorry, mi código es largo. Pero recuerda que no sólo imprime el triángulo sino que hace el arte adicional de imprimir el desarrollo del binomio en dos líneas (una para la base y otra para el exponente), aunque eso no era exactamente lo se había pedido. Sólo quise ir más allá e imitar un poco la función "pretty" de despliegue por consola de expresiones algebraicas de algunos paquetes como Maple, Matlab.

Y bueno ..... la verdad ya yo me rindo con este tema, jajaja. Que sigan otros  ;D
#132
Programación C/C++ / Re: tableros
18 Marzo 2014, 02:04 AM
Ya se volvieron unos artistas  :o  :o  :o !!! Mis respetos.
#133
Leosansan, para que puedas observar el binomio "bien" debes usar una fuente ancho constante de las letras (teletipo), o en el caso de este foro encerrado por las etiquetas [ tt ]. Con ello, para N=5:

(a + b)^5 es:

5     4       3 2      2 3      4    5
a  + 5a b + 10a b  + 10a b  + 5ab  + b


Claro, indiqué que la salida no sale correcta si la longitud del desarrollo del binomio excede de una línea en la terminal que uses. Tu terminal por lo visto hace scroll horizontal, por lo que no "salta" las líneas que excedan del ancho de pantalla, y entonces las expresiones muy largas se siguen viendo bien. No así la mía ue tiene un ancho fijo.

Imprimir el triángulo no es problema, pues ya tengo la función que lo genera, sólo un par de for ya lo imprimes. Aclaro que por razones de eficiencia sólo ocupo la parte "triangular izquierda" de la matriz, pues sólo se usan los números combinatorios <i,j> para j=0 hasta j=i. Entonces la matriz queda con forma de triángulo rectángulo y no isósceles. Esto puede parecer raro, pero es común en la programación de métodos numéricos  ;)

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

Y por cierto, hablando del tema de la eficiencia, demás está decir que generar los combinatorios mediante suma recursiva de la fila anterior es mejor que hacerlo con factoriales.

Aclamo tu profusa explicación sobre combinatorios, triángulo de Pascal y binomio de Newton, es exactamente como dices. No quise poner imágenes aquí porque a veces entorpecen un poco la carga de la página (los archivos de imágenes pueden ser voluminosos), por eso cambié a una representación sucinta de los binomiales como <i,j>, aunque menos visual que la tuya. Sabes que soy un minimalista, jeje.

========================================
EDITO (réplica)

Pues bien, para cumplir con el objetivo planteado de imprimir el triángulo creo que lo más simple sería obtener la longitud de la línea más larga del triángulo (para ello la función auxiliar line_width()), restarle la longitud de la línea actual, y tomar el cociente entero de dividir entre dos. Esta sería la separación entre el margen izquierdo y la primera posición donde vamos  empezar a imprimir la línea. Bueno ....... ya se capta la idea.

Salida (N = 10) :

                 1
                1 1
               1 2 1
              1 3 3 1
             1 4 6 4 1
           1 5 10 10 5 1
         1 6 15 20 15 6 1
        1 7 21 35 35 21 7 1
      1 8 28 56 70 56 28 8 1
    1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1

No se si lo quieres de otra forma ..., o si ya pude terminar con bendito triángulo jajaja  :laugh: (broma). El código:
Código (cpp) [Seleccionar]

int line_width( int **, int );
void print( int **, int );

int main( ) {

/* ......... (resto del programa) ................. */
/* Imprimir el triangulo */
   print( A, N );
   putchar('\n');
/* ..........(resto del programa) .............. */
}

/* Calcula el ancho impresa de una linea del triangulo de Pascal */
int line_width( int ** A, int i ) {

   int j, width = 0;

   if ( i > 0 ) { /* lineas 1 en adelante */
      for ( j = 0; j <= i; j++ )
         width += digits( A[i][j] );
      width += i; /* (los espacios en blanco) */
      return width;
   }
   else if ( i == 0 ) /* linea cero */
      return 1;
   else /* argumento negativo */
      return 0;
}

/* Imprime el triangulo de Pascal de orden N */
void print( int **A, int N ) {

   int MAX_width, width, i, j;

   /* linea mas ancha del triangulo */
   MAX_width = line_width( A, N );

   for ( i = 0; i <= N; i++ ) {
      width = line_width( A, i ); /* linea actual */
      j = 0;
      while ( j++ < (MAX_width - width)/2 )
         putchar(' ');
      for ( j = 0; j <= i; j++ )
         printf( "%d ", A[i][j] );
      putchar('\n');
   }
}
#134
¿Qué se quiere decir exactamente con que el programa "revienta"? ¿Fuga de memoria, terminación anormal?

Hice una prueba, tomé el unsigned 1 y fui desplazando sus bits a la izquierda e imprimiendo el resultado por bits (con las mismas funciones dadas aportadas en el tema), para observar lo que ocurre luego del desplazamiento número 31.

Para mayor seguridad mandé imprimir antes la cantidad de bits de la representación de enteros en mi máquina y verificar que son 32. El resultado del programa:

En esta maquina los enteros ocupan 32 bits
29: 00100000 00000000 00000000 00000000
30: 01000000 00000000 00000000 00000000
31: 10000000 00000000 00000000 00000000
32: 00000000 00000000 00000000 00000000
33: 00000000 00000000 00000000 00000000

Se aprecia que en los desplazamientos 32 en adelante simplemente se pierde el bit y el número queda compuesto por ceros, pero la consola no me indica terminacióna anormal. Consulté el estado de salida del proceso (echo $?, para bash) y fue 0 (normal).

¿Qué me dicen ustedes?

====================
(EDITO) Ya comprendí el dilema, creo que no estamos hablando de lo mismo. La instrucción "num << 31" tendrá un comportamiento indefinido (pero no un error fatal) si el operando a la derecha es mayor que la longitud en bits del operando a la izquierda. Lo que yo hice fue diferente, ejecutar "num << 1" reiterativamente más de 31 veces.
====================

Código (cpp) [Seleccionar]

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

void imprimir(unsigned num);

int main( ) {

   unsigned num = 1;
   int i;

   printf("En esta maquina los enteros ocupan %d bits\n",
          sizeof(unsigned) * CHAR_BIT);

   for (i = 0; i < 34; num <<= 1, i++ )
      if ( i > 28 ) {
         printf( "%d: ", i );
         imprimir( (unsigned) num );
      }

   return 0;
}

void imprimir(unsigned num)
{
   unsigned msb = 1U << sizeof(unsigned) * CHAR_BIT - 1;
   size_t i;
   size_t j;

   for (i = 0; i < sizeof(unsigned); i++) {
      for (j = 0; j < CHAR_BIT; j++) {
         putchar(num & msb ? '1' : '0');
         msb >>= 1;
      }
      putchar(' ');
   }
   putchar('\n');
}
#135
Cita de: amchacon en 15 Marzo 2014, 23:03 PM
Aunque si la función pascal devuelve NULL, el main no lo comprueba y lo usa de todas formas. Lo que generaría un error de ejcución.

Por estos olvidos se inventaron las excepciones de C++ ^^

Bueno aunque ahí la culpa es del programador (yo  ;D), se me pasó ese detallito. Hay que cambiar la línea a:
Código (cpp) [Seleccionar]

if ( ( A = pascal( N ) ) == NULL ) return -1;

y creo que soluciona el problema.




leosansan, el error fue porque te faltó el argumento pasado por línea de comandos. Para solucionarlo simplemente compila y cuando te genere el ejecutable abre una ventana de Símbolo del Sistema, y cámbiate ( con el comando cd) al directorio donde tienes el ejecutable. Por ejemplo, supón que se creó en "C:\Documentos\Leo\bin", entonces pones en la consola

cd C:\Documentos\Leo\bin

(si usas una IDE a veces puede ser difícil inspeccionar dónde exactamente crea el .exe). Luego de ello, teclea por ejemplo:

binomio 5

para que te calcule con N=5.

........
Si no quieres hacer nada de eso (o no te funciona), sólo modifica el main() para que pida el valor de N con scanf(), y ya  :D

..........
(EDITO)

No me había dado cuenta que amchacon ya arregló el código para que no requiera argumentos por línea de comandos. Thanks!!

Y gracias también por los elogios a mi programa  :D
#136
Programación C/C++ / Re: Ayuda con programa
16 Marzo 2014, 01:00 AM
En ese caso es más sucinto:
Código (cpp) [Seleccionar]

char coincidencia(const char letra,const char* diccionario)
{
  int i = 0;
  while ( diccionario[i] )
  {
      if (letra == diccionario[i++]) return 1;
  }
  return 0;
}
#137
Programación C/C++ / Re: dudas con strcpy
15 Marzo 2014, 23:26 PM
Amchacon, por eso dije ... "supongo", porque la verdad yo no se.

No lo se porque en lo particular siempre trato de programar de forma "segura", atendiendo a las especificaciones de la biblioteca estándar de C, y la verdad pocas veces me he puesto a ver qué pasa si hago tal o cuál cosa de manera insegura. Prefiero irme de una vez por lo sano, y así evitar crasheos, etc.

Pero respecto a lo de varios lenguajes lo que quise decir es que específicamente en el aprendizaje de C/C++, me parece más adecuado aprender primero a programar correctamente en C, y luego pasarse a C++ el cual básicamente amplica las capacidades del primero. Eso en lugar de mezclar el C y el C++, lo que constituye una mala costumbre según el criterio unánime creo que todos los que opinamos aquí.

Otra mala costumbre, y lamentablemente extendida entre algunos maestros, es no guiarse por el C estándar. Referirse a gotoxy(), getch(), etc., de la manera más natural (y descarada), sin especificar ni aclarar que son no funciones estándares. No digo que no usen esas funciones, pero deben dejar en claro que son privativas y generalmente usadas en Windows.
#138
Programación C/C++ / Re: Ayuda con programa
15 Marzo 2014, 23:14 PM
Casualmente hace unos días estaba pensando en cómo podría hacer un código que imitara la función estándar strtok() .... aunque al final no me senté a hacerlo.

Pero ya hoy obtuve la respuesta, y una solución hábil por cierto  ;D
#139
Programación C/C++ / Re: Ayuda con programa
15 Marzo 2014, 22:11 PM
Aunque no queda mucho que aportar aquí, la idea fundamental es que si se haya espacio imprimir en su lugar un '\n', de otro modo imprimir el carácter normal. Se puede mejorar un poco usando isspace() (requiere <ctype.h>) para que dicho reemplazo ocurra no sólo con ' ', sino con cualquier carácter de espacio (tabulador, etc).

Presento mi versión enteramente en C. Usa un modo seguro de ingreso de datos usando fgets() (controla la cantidad de caracteres que se ingresan) y atendiendo a la recomendación de leosansan su usa la función estándar getchar() en lugar de getch(). Su salida:

Intro frase: Anita lava la tina
Anita
lava
la
tina


Código (cpp) [Seleccionar]

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

void mi_strtok( char *frase );

int main( ) {

   char frase[101];

   printf("Intro frase: ");
   fflush( stdout );
   fgets(frase, 101, stdin);

   mi_strtok( frase );

   putchar('\n');
   return 0;
}

void mi_strtok( char *frase ) {

   int i;
   char c;

   i = 0;
   while ( ( c = frase[i++] ) != '\0' ) {
      if ( !isspace(c) )
         putchar(c);
      else
         putchar('\n');
   }
}
#140
Programación C/C++ / Re: Problema extraño
15 Marzo 2014, 21:59 PM
Cita de: amchacon en 13 Marzo 2014, 22:12 PM
En España lo usan gente de cultura muyyy baja... Nosotros les llamamos "Canis"

Imaginate a esos especimenes escribiendo en el facebook. Su escritura no es muy diferente de lo que sale en el ejemplo xD.


Sinceramente me terminará doliendo la cabeza de leer frases en ese lenguaje  :laugh:  :huh: