Prácticas de análisis de algoritmos [ESCOM]

A lo largo del semestre, en la materia de Análisis de Algoritmos que llevo con el profesor Edgardo Franco tenemos que realizar varias prácticas. Las prácticas consisten en programar algoritmos conocidos para analizar su comportamiento, tanto en tiempo como en memoria consumida, mientras resuelven problemas de "gran" tamaño.

Muchas (si no es que todas D:) estarán hechas para C, para Linux, esto debido a la librería empleada para medir los tiempos que consume la ejecución del algoritmo. Para facilitar la compilación cada práctica cuenta con un archivo Makefile, el cual contiene todas las instrucciones para compilar y ejecutar las prácticas. Dado que tenemos que analizar los tiempos de ejecución y a veces estos pueden ser muchos, para la ejecución de cada programa redireccionamos la salida estandar para que escribiera directamente a un archivo que podemos manejar sencillamente en una hoja de cálculo. Esto se puede ver en el archivo .sh que acompaña a cada práctica.

Todas las prácticas tienen comentarios, unas más, otras menos, pero los tienen. Aún así si queda alguna duda pues no dudes en preguntar. Otra cosa importante es que estas son solo las propuestas de solución que presentamos, no las copies directamente, basate en ellas o usa porciones del código, eso se vale. El link de descarga está al final del artículo ;).

Hasta el momento hemos realizado 3 prácticas:

Práctica 1: "Pruebas a posteriori (Algoritmos de ordenamiento)"

Con base en el archivo de entrada proporcionado que tiene 200,000 números diferentes. Ordenarlo bajo los siguientes métodos de ordenamiento y comparar experimentalmente las complejidades de estos.
  • Burbuja (Bubble Sort)
  • Burbuja Simple
  • Burbuja Mejorada
  • Inserción (Insertion Sort)
  • Selección (Selection Sort )
  • Shell (Shell Sort)
  • Ordenamiento con árbol binario de busqueda (Binary Search Tree)

Práctica 2: "Análisis temporal y notación de orden (Algoritmos de busqúeda)"

Con base en el ordenamiento obtenido a partir del archivo de entrada de la práctica 01 que tiene 200,000 números diferentes. Realizar la búsqueda de elementos bajo 3 métodos de búsqueda y variantes con procesos ligeros, realizar el análisis teórico y experimental de las complejidades; así como encontrar las cotas de los algoritmos.
  • Búsqueda lineal o secuencial (No recursiva)
  • Búsqueda binaria o dicotómica (No recursiva)
  • Búsqueda en un árbol binario de búsqueda (No recursiva)
  • Modificar los tres algoritmos para trabajar con procesos ligeros (Hilos).

Práctica 3: "Divide y vencerás (Rotación de una imagen)"

Implementar el algoritmo de rotación de imágenes que emplea la técnica divide y vencerás. La imágen a girar es cuadrada, y es un .bmp de 24 bits.

Descargas:
Como desde hace tiempo, puedes seguir el proyecto en GitHub analizando-algo (recomendado)
O descargar cada una de las tres prácticas de manera individual:
Práctica 3
Práctica 2
Práctica 3


¡Saludos!
@fferegrino :)

"Mapeando" de procedimientos almacenados a clases en C#


Hace rato, mientras no tenía clase me dispuse a escribir un pequeño programita para facilitarme la vida con algo (asquerosamente tedioso) que tenía que hacer. Y es que lo que tenía que hacer hasta parece arcaíco: Se trata de hacer consultas desde una aplicación web a una base de datos mediante procedimientos almacenados, para ello hay que generar una clase asociada al procedimiento para facilitar la persistencia de los datos dentro de la aplicación.

Hay consultas enoooooooooooooooooooooormes, inclusive hay algunas de más de 20 o 30 columnas lo cual representa perder mucho tiempo creando la clase asociada, aunque a decir verdad yo no lo hago por el tiempo, sino por el aburrimiento que representa hacerlo. Acá mi propuesta de solución:

La idea que se me ocurrió fue colocarles una especie de "clave" para conocer el tipo de dato de cada columna así como el nombre que usaría para ella dentro de la aplicación. La clave elegida fue: --|tipo de dato|nombre dentro de la aplicación  dada la facilidad con la que una cadena de ese tipo es fácilmente encontrable usando expresiones regulares, para ello se requiere del siguiente patrón: --\|[a-zA-Z0-9]+\|[a-zA-Z0-9]+. Además en el programa usé una plantilla de texto T4 para generar el código, esas plantillas son útiles para generar código como en esta ocasión, el ejemplo es sencillo y fácil de entender.

Colgué el proyecto completo en GitHub para que todos pudieran descargarlo, yo pienso que le seguiré añadiendo funcionalidad conforme la vaya necesitando (hasta que me aburra de hacer otra cosa :P).

¡Saludos!
@fferegrino :)

Mis apps para Windows/Windows Phone 8

Últimamente he andado muy ocupado (no tanto), haciendo unas cuantas aplicaciones para Windows Phone 8 y Windows 8 esperando ser parte del programa Microsoft Student Partners 2013.  Al momento llevo 6 aplicaciones publicadas entre la Windows Store y la Windows Phone Store. De algunas ya les he contado y de otras no. En fin, son estas:

Cuantos días
¿Alguna vez has querido saber cuantos días faltan para una fecha importante? Ahora lo puedes saber, con Cuantos días para Windows Phone 8 ten siempre a la vista cuantos días faltan para tu cumpleaños, el re-estreno tu serie favorita o cualquier otra cosa.


C0NV3R7
Un sencillo convertidor entre sistemas numéricos. Convierte de los sistemas binario, octal, decimal y hexadecimal.
De esta ya les había hablado.



RecetApprio(La obra maestra)
Un recetario hecho para ti, que no tienes ganas ni dinero para cocinar algo "gourmet". Recetas simples y sencillas, elaboradas por un experto en la materia de alimentar personas de forma deliciosa, rápida y barata.
En esta conté con la colaboración en el diseño de Julio Montaño, al cual agradezco mucho :). Además aprovecha de los servicios en la nube de Windows Azure.


BombFlipper
Diviértete con este juego que combina el buscaminas y el sudoku para entretenerte como no tienes idea, ejercita tu cerebro tratando de llegar al nivel más alto que puedas y cuando estés ahí comparte tu récord con tus amigos.


El Agente
Diviértete ayudando a este despistado agente a recuperar los papeles que el viento se llevó, pero cuidado, hay algunos papeles que quizá no desee recuperar.


Ojalá puedan descargarlas y valorarlas, así mismo si estás interesado en el desarrollo de alguna de ellas mándame un correo y con gusto vemos cómo hacerle.

¡Saludos!
@fferegrino :)

Invertir una cadena [C#]

Durante la plática de reclutamiento para Microsoft que hubo hace unos días en la ESCOM hicieron una prueba a los asistentes, la prueba consistía en escribir el código de dos funciones:
Una capaz de invertir una cadena, es decir, pasar de "this is a string" a "gnirts a si siht"
Otra muy similar pero solo debía invertir las palabras, pasando de "this is a string" a "siht si gnirts"
Basándonos en un prototipo de función más o menos así:
char* reverse(const char* str)

El lenguaje a usar era cualquiera con el que te sintieras cómodo, C#, C, Java... en fin. La idea era que usaras la menor cantidad de herramientas provistas por el framework o por el lenguaje que escogiste (¡no se valía el .Reverse()!), es decir que todo lo hicieras "artesanalmente". Eso si, no recuerdo muy bien cuanto tiempo dieron para escribir.

Por suerte yo me había encontrado con un problema similar unos días antes, así que creo que no me fue tan mal en esta. Mi solución la propuse en dos lenguajes, C para la primera y (por cuestiones de tiempo) C# para la segunda. Ahora vengo acá a colocar mis soluciones un poco más pensadas y totalmente funcionales escritas en C#:

using System;
using System.Linq;
using System.Text;

namespace ReverseStringsMsft
{
    class Program
    {
        static void Main(string[] args)
        {
            string s = "this  is  a string";
            string res = Reverse(s);
            string resWord = ReverseWords(s);
            Console.WriteLine(s);
            Console.WriteLine(res);
            Console.WriteLine(resWord);
            Console.Read();
        }

        /// <summary>
        /// Invierte una cadena
        /// </summary>
        /// <param name="str">La cadena que será invertida</param>
        /// <returns>Una nueva instancia de String</returns>
        public static string Reverse(string str)
        {
            if (str == null)
                return null;
   // Convertir a un arreglo
            char[] cr = str.ToArray();
   // Llamamos a la funcion para toda la cadena
            Reverse(cr, 0, cr.Length - 1);
            return new string(cr);
        }

        /// <summary>
        /// Invierte las subcadenas (separadas por espacios) contenidas dentro de una cadena
        /// </summary>
        /// <param name="str">La cadena que será invertida</param>
        /// <returns>Una nueva instancia de String</returns>
        public static string ReverseWords(string str)
        {
            if (str == null)
                return null;
   // Convertir a un arreglo
            char[] cr = str.ToArray();
            int wordStart = 0;
            int end;
   // Recorremos la cadena para encontrar espacios
            for (int i = 0; i < cr.Length; i++)
            {
                char c = cr[i];
    // Por cada espacio o cada vez que lleguemos al final de la cadena
    // llamaremos a la funcion especialmente para la ubicacion de 
    // la palabra encontrada
                if (c == ' ' || i == cr.Length - 1)
                {
                    end = i - 1;
                    Reverse(cr, wordStart, end);
                    wordStart = i + 1;
                }
            }
            return new string(cr);
        }

        /// <summary>
        /// Cambia de posición los caracteres desde <paramref name="start"/> a
  /// <paramref name="end"/> hasta que todos estén invertidos
        /// </summary>
        /// <param name="str">El arreglo a ser invertido</param>
        /// <param name="start">Inicio</param>
        /// <param name="end">Final</param>
        private static void Reverse(char[] str, int start, int end)
        {
            for (; start < end; start++, end--)
            {
    // Cambiamos uno a uno los caracteres desde la posicion
    // inicial hasta la final, y aumentamos las variables para irlos 
    // intercambiando como deseamos
                char aux = str[start];
                str[start] = str[end];
                str[end] = aux;
            }
        }

    }
}


¡Saludos!
@fferegrino :)

C0NV3R7, convertidor entre bases numéricas


Esta vez vengo a contarles que el otro día mientras divagaba mi mente en la clase de Fundamentos de diseño digital se me ocurrió una "idea" para una app. Y es que digo "idea" porque no es nada nuevo, en clase estábamos viendo los distintos sistemas numéricos y la conversión entre ellos. Y pues de eso se trata la app: de un conversor numérico entre bases, pones un número y en seguida consigues su equivalente en octal, binario, decimal y hexadecimal.

En realidad el código es más que sencillo. La gran novedad es que en esta traté de emplear a fondo el patron de diseño MVVM, dejando toda la lógica de la aplicación en un ensamblado aparte, que usé para las plataformas Windows 8 y Windows Phone 8. En realidad la aplicación es tan sencilla que la interfaz usada en una es igual a la otra.

Pongo el link a las aplicaciones en la Windows Store y en la Windows Phone Store


Además del código del que salieron ambas aplicaciones:

C0NV3R7.rar

PD: Todo lo que he aprendido sobre Windows Phone fue gracias a estos vídeos hechos por Rodrigo Díaz Concha. Chéquenlos, están muy buenos.

¡Saludos!
@fferegrino :)

Proyectos de Compiladores, ESCOM

Esta vez los saludo con un megapack: los proyectos de la asignatura de Compiladores en la ESCOM, entre ellos un conversor expresión regular-AFN-AFD (Java) y un analizador léxico-sintáctico (C). Y es que por problemas técnicos (y un poco de flojera) no los subí en el tiempo en el que fueron realizados.

La asignatura la cursé con el profesor Juárez Gambino Omar, junto con mi equipo: Cruz Cruz Jorge y Gonzales Rodríguez  Javier (@newbie_geek). A lo largo del semestre aprendí demasiado, y parte de ello fue que había mucho tiempo para practicar lo aprendido, aplicando el conocimiento en varias practicas a lo largo del curso.

La primera, fue un programar un analizador léxico, código y un sencillo reporte el cual coloco a continuación:

La segunda, el conversor de expresión regular a autómata finito no determinista, y de autómata finito no determinista a uno determinista. Este está hecho en Java:

La tercera práctica consistió en utilizar el lenguaje Flex para generar un analizador léxico (muy básico) para C, si ya conocen el lenguaje sabrán que la extensión (por convención) es .l:

Para la cuarta práctica comenzamos a emplear Bison, para ayudarnos en la construcción de un analizador sintáctico, la práctica fue individual, porque en realidad era sencilla. Basarnos en un ejemplo y hacer una calculadora:

La quinta y última práctica fue un analizador léxico y sintáctico para C haciendo uso de Flex y Bison juntos, en teoría es la más complicada, y que requirió más trabajo pero no por eso faltó:

La finalidad de poner estos códigos y reportes como descargables es que tú los puedas checar, leer, tratar de entender y posteriormente implementar a tu modo. No simplemente los descargues y entregues, o lo que es peor, no los bajes y cambies los nombres a las variables (nos gustan los nombres de nuestras variables, no los cambies). Como dicen "allá afuera no vas a encontrar las cosas hechas", así que lo ideal sería que estudies y trates de comprender el código.

Si hay alguna parte que no te queda clara puedes comentarla debajo o enviarme un correo, ya de menos un tuít. Pero hagas lo que hagas, NO COPIES.

¡Saludos!
@fferegrino :)

BombFlipper - Windows 8

Sé que tengo rato programando para Windows 8 y la verdad es que es divertido. Durante unos de esos arranques se me ocurrió hacer una versión de un minijuego incluído dentro de otro juego, el no tan famoso Voltorb Flip. No todo fue miel sobre hojuelas, puesto que sería mi primera aplicación hecha desde cero. 

La más dura decisión fue sobre qué tecnología escoger, dura decisión entre C# y XAML o HTML y JavaScript. De C# conozco mucho más que de JS, pero de HTML sé mucho más que de XAML Sinceramante para la interfaz prefería usar la magia de HTML con el poder de CSS, debido a la experiencia que tengo usándolo (además de que la otra opción era completamente desconocida para mi). Sin embargo, para la parte de la lógica solo pensaba en usar C# debido a la cantidad de cálculos necesarios para implementar el juego.

Al final me decidí por C# y su acompañante, porque se me hizo la opción más sólida y por que representaba un reto aprender sobre el desarrollo de interfaces, y es que, aunque el producto final no es de lo más pulcro considero que fue un buen aprendizaje.

Aún queda mucho por hacer, más que anda en la interfaz de usuario porque ni a mi me resulta muy amigable, los invito a descargar el juego en la liga que está más abajo. Si lo prueban les pudo que me comenten aquí o al correo su opinión y sugerencias.



¡Saludos!
@fferegrino :)