3 de agosto de 2018

Comentarios y sugerencias.

   Esta entrada tiene como intención principal, recolectar aquellos comentarios que los lectores deseen hacer acerca de algún punto o tema relacionado con el blog.

   En general he tratado de cuidar, en todo el blog, aquellos aspectos que hagan más accesible tanto la lectura como su correspondiente comprensión; sin embargo, es posible que algunas cosas que podrían parecer claras no lo sean del todo para la amplia diversidad de lectores, por lo que agradeceré de manera anticipada al lector bien intencionado, me informe de cualquier error identificado o sugerencia que permita mejorar el contenido.

   Dejo abierta la sección de comentarios para recibirlos y poder dar respuesta, en la medida de mis posibilidades, a cada uno de ellos.

   Quedo en deuda con todas las personas que me han escrito y ayudado a mejorar con sus comentarios, así como con los estudiantes que me han hecho valiosas aportaciones en más de un sentido.
 
    Agradezco particular y encarecidamente con el más profundo de mis afectos a la Ing. Thelma García Reyes, quien ha sido piedra angular tanto en el desarrollo inicial como en la revisión de lo que en su momento fue un libro y ahora un blog; sin su inestimable ayuda y entusiasmo cuando el desánimo se montaba en mis espaldas, seguiría atorado en los escollos del desarrollo y elaboración de imágenes, revisión, correcciones, y un largo etcétera. 
 
    En este mismo sentido agradezco y aprecio el apoyo del Dr. Tomás Balderas Contreras, quien no sólo me hizo el favor de escribir el prólogo del libro, sino que sus valiosos comentarios respecto a algunos de los aspectos técnicos del contenido, son insalvables.
 
    Aún con lo anterior, cualquier error que persista en este blog y en cualquier parte de su contenido es únicamente atribuible al autor.


27 de noviembre de 2017

Ejercicios selectos (matrices).

  1. Considere el Ejemplo 6.7. ¿Qué pasa si hay más inicializadores que elementos físicos? Pruebe dicha situación en los dos esquemas de inicialización planteados en el blog.
  2. Escriba un programa que pruebe la función suma del Ejemplo 6.8.
  3. Modifique la función leeMatriz del Ejemplo 6.7 para que almacene valores de tipo float en la matriz matriz. Una vez que haya probado su función, agréguela a la biblioteca de funciones del Ejemplo 6.8.
  4. Modifique la función imprimeMatriz del Ejemplo 6.7 para que imprima los valores de tipo float de la matriz matriz. Una vez que haya probado su función, agréguela a la biblioteca de funciones del Ejemplo 6.8.
  5. Escriba un programa que defina y pruebe una función con el siguiente prototipo: void resta(float a[ ][N], float b[ ][N], float c[ ][N], int m, int n). La función deberá calcular en la matriz c la resta de la matriz a menos la matriz b de manera análoga a como lo hace la función suma del Ejemplo 6.8.
  6. Agregue la función resta del ejercicio anterior, a la biblioteca de funciones del Ejemplo 6.8.
  7. Escriba un programa que defina y pruebe una función con el siguiente prototipo: void imprimeTranspuesta(float a[ ][N], int m, int n). La función deberá imprimir en la salida estándar la matriz transpuesta de a. La matriz transpuesta se genera convirtiendo los renglones en columnas y viceversa.
  8. Escriba un programa que defina y pruebe una función con el siguiente prototipo: void transpuesta(float a[ ][N], float aT[ ][N],int m, int n). La función deberá generar en la matriz aT la matriz transpuesta de a. La matriz transpuesta se genera convirtiendo los renglones en columnas y viceversa.
  9. Agregue la función transpuesta del ejercicio anterior a la biblioteca de funciones del Ejemplo 6.8.
  10. Escriba un programa que defina y pruebe una función con el siguiente prototipo: int esSimetrica(float a[ ][N], int n). La función deberá determinar si la matriz a es o no simétrica. Una matriz simétrica es aquella que es igual con su matriz transpuesta.
  11. Agregue la función esSimetrica del ejercicio anterior, a la biblioteca de funciones del Ejemplo 6.8.
  12. Escriba un programa que defina y pruebe una función con el siguiente prototipo: void producto(float a[ ][N], float b[ ][N], float c[ ][N], int m, int n, int l). La función debe calcular el producto de las matrices  a y b almacenando el resultado en c. Para poder realizar este ejercicio, investigue cómo se define y obtiene el producto de matrices.
  13. Agregue la función producto del ejercicio anterior a la biblioteca de funciones del Ejemplo 6.8.
  14. Escriba una función que determine la suma de los elementos de la diagonal principal de una matriz.
  15. Escriba una función que determine la suma de los elementos de la diagonal secundaria de una matriz.
  16. Un cuadrado mágico es una matriz de n x n donde n es impar, en donde se colocan números enteros en cada una de sus entradas y que además cumple con las siguientes características:
    • La suma de los números de cualquier línea (horizontal, vertical o diagonal) será siempre la misma. A esta suma se le denomina constante mágica.
    • Todos los números almacenados en un cuadrado mágico deben ser distintos.
    Con base en lo anterior, escriba una función con el siguiente prototipo:

    int cuadradoMagico(int c[ ][N], int n);

    Dado un cuadrado c de dimensiones lógicas n, la función determina si representa (regresa 1) o no (regresa 0) un cuadrado mágico. Ejemplo:

    4     9     2
    3     5     7
    8     1     6
    es un cuadrado mágico.
  17.  Haga un programa que implemente el juego del gato (tic tac toe). En este programa el usuario jugará en contra de la computadora. Utilice una matriz de tipo char e inicialícela con espacios en blanco. Utilice "O" para la computadora y "X" para el usuario. Haga su algoritmo tan elaborado como considere, no permita que el usuario gane fácilmente; sin embargo, una posibilidad es que cuando sea el turno de la computadora, simplemente recorra la matriz buscando una posición que no esté ocupada.
  18. Considere una implementación básica del Juego de la Vida con base en una matriz de 0's y 1's. El Juego de la Vida fue diseñado por el matemático británico John Horton Conway en 1970.
Arreglos de n dimensiones.
  1. Las figuras del arreglo tridimensional discutidas en el blog (Arreglos de n dimensiones) muestran en gris algunos de los elementos del arreglo de tres dimensiones. Denote todos los elementos visibles (para ambas) de dicho arreglo siguiendo la nomenclatura del lenguaje C.
  2. De manera análoga a lo descrito en la entrada Arreglos de dos dimensiones, dibuje y describa la representación física en la memoria del arreglo tridimensional del ejercicio anterior. Sugerencia: la representación en memoria se realiza también de manera lineal: los renglones de la primera matriz, después los de la segunda matriz, etcétera, la representación de malla puede ayudarle a visualizar mejor la representación.
  3. Basándose en el Ejemplo 6.9, escriba un programa que generalice la idea planteada para definir, inicializar, e imprimir en la salida estándar un hipercubo.
  4. Basándose en el Ejemplo 6.9, escriba un programa que generalice la idea planteada para definir, inicializar, e imprimir en la salida estándar un arreglo de cinco dimensiones cada una con un tamaño distinto, por ejemplo: dos para la primera dimensión, tres para la segunda, cuatro para la tercera y así sucesivamente.

1 de agosto de 2017

Diseño y consideraciones.

Diseño básico de programas estructurados.
   La esencia del diseño mostrado a continuación está basado principalmente en las reglas para la formación de programas estructurados propuestas en [Deitel].

   Al conectar de forma arbitraria o poco cuidadosa los símbolos de los diagramas de flujo, se puede incurrir en diagramas de flujo no estructurados como el de la siguiente figura:

Diagrama de flujo no estructurado.

   La generación de diagramas de flujo estructurados requiere de utilizar estructuras de control con una única entrada y una única salida, de tal manera que sólo haya una forma de entrar y una de salir de la estructura de control.

   Las estructuras de control descritas en las entradas Diagramas de flujo y Pseudo código cumplen con lo anterior. Se deja como ejercicio al lector el validar y verificar dicha situación; en éste sentido, observe que aunque la estructura de selección múltiple en el diagrama de flujo parece tener más de una salida, sólo una de ellas es finalmente procesada, y que independientemente de la(s) sentencia(s) que haya(n) sido seleccionada(s), su salida converge a un único punto de salida representado por el conector.

   Reglas para la formación de algoritmos estructurados.
   A continuación se muestran las reglas para la construcción de algoritmos estructurados, mismas que bien podrían denominarse como “Algoritmo para la construcción de algoritmos estructurados”:
  1. Empiece con el diagrama de flujo más simple.
  2. Cualquier rectángulo (acción, sentencia, etc.) puede ser reemplazado por dos rectángulos de manera secuencial. Esta es la regla de apilamiento.
  3. Cualquier rectángulo puede ser reemplazado por cualquier estructura de control. Esta es la regla de anidamiento.
  4. Aplicar de manera sucesiva las reglas 2 y 3.
   En la siguiente figura se muestra la regla 1 y la aplicación repetida de la regla 2.

Aplicación de las reglas 1 y 2.

   La aplicación de las reglas anteriores derivan siempre en un diagrama de flujo estructurado con una apariencia clara de bloques constructivos [Deitel].

   Por otro lado, la siguiente figura muestra la aplicación de la regla de anidamiento al diagrama de flujo más simple que puede haber. Note que los bloques han sido substituidos por estructuras de selección doble y de repetición.

Aplicación de la regla 3.

   Por último, es importante resaltar que la aplicación de la regla 4 genera estructuras más grandes, más complejas y con un nivel de anidamiento más intrincado. Adicionalmente, cabe mencionar también que los diagramas de flujo que resultan de aplicar las reglas descritas anteriormente, constituyen el conjunto de todos los diagramas de flujo estructurados posibles, y por lo tanto, también el conjunto de todos los posibles programas estructurados [Deitel].

Consideraciones finales.
   La programación estructurada no debe confundirse con el conocimiento de un lenguaje de programación. La programación estructurada es un modelo de programación y es independiente del lenguaje que se utilice para su implementación.

   El estudio y el conocimiento de técnicas, así como el desarrollo de algoritmos previos a la fase de implementación, no sólo es una buena práctica de programación, sino un principio esencial de la Ingeniería de Software.

   Por todo lo anterior, si lo que se quiere es llevar a buen fin sus proyectos de programación y evitar dolores de cabeza innecesarios, debe tomar en consideración que, antes de enfrentarse en una lucha encarnizada teniendo a la computadora como su adversario y al lenguaje de programación como arma, debería, antes de escribir su primera línea de código, hacer un análisis profundo del problema a resolver, elaborar un plan de solución general, especificar gradualmente dicho plan, y realizar un conjunto de pruebas representativas.