sábado, 5 de julio de 2014

Electiva Hipotética: Introducción a la Programación Competitiva

Actualmente mucho departamentos de la USB han sufrido una fuga importante de personal docente, lo que ha supuesto una reducción significativa en la cantidad de cursos electivos que se ofrecen. ¿Por que? Las cargas docentes de los profesores restantes se cubren en materias obligatoria y básicas. Aún así, es cada vez más difícil cubrir todas las necesidades docentes en estas materias. Esto supone un buen grado de frustración a los profesores, ya que no les es posible dictar cursos en sus diferentes áreas de especialización y tener acceso a estudiantes interesados en dichas áreas para futura investigación y proyectos de grado.

En mi caso, tengo la fortuna de que mi principal área de especialización (lenguajes de programación) tiene tres materias obligatorias en el pensum de Ingeniería de la Computación en la USB:

  • Lenguajes de Programación I.
  • Laboratorio de Lenguajes de Programación.
  • Traductores e Interpretadores.

Por lo tanto, suelo estar asignado al menos a una de ellas por trimestre. ¡Son asignaturas que me encantan! Pero como todo, puede volverse monótono. En el caso de traductores, la he dado ya 2 veces como preparador, 3 veces como ayudante docente y 3 veces como profesor (con miras a una más, el trimestre que viene). Sería interesante poder trabajar algunas de las otras áreas que me interesan e incluso comenzar a investigar nuevas áreas. Con esto en mente, comenzaré una serie de artículos en este blog con "electivas hipotéticas". Esto es, con materias electivas que podrían comenzar a abrirse algún día cuando la USB vuelva a su antigua grandeza y haya mayor libertad para ser creativo.

Mundial ACM-ICPC 2010 en Harbin, China.
(Aquí participó un equipo de la USB)

De estas electivas hipotéticas plantearé un contenido y un plan de evaluación tentativos, de los cuales me encantaría tener feedback. ¿Quién sabe? Quizá se pueda abrir alguna de estas en un futuro no tan lejano (soñar no cuesta nada, jajaja). A continuación entonces, la primera de la serie de electivas hipotéticas.

Asignatura: Introducción a la Programación Competitiva
Créditos:
Objetivo principal: Familiarizar al estudiante con las destrezas técnicas necesarias para participar en competencias de programación al estilo ACM-ICPC
Contenido:
  • Semana 1: Introducción a las competencias de programación, sus herramientas y reglas. Medición general del nivel de los estudiantes previo al curso. Dinámica individual y grupal.
  • Semana 2: Problemas ad-hoc: Saber interpretar bien un enunciado, la especificación de entradas y salidas, restricciones de las mismas y tiempos límite.
  • Semana 3: Algoritmos voraces (greedy): ¿Como reconocerlos? Los peligros de confiar en una solución voraz. Criba de Eratóstenes. Búsqueda binaria. Potenciación logarítmica y Fibonacci.
  • Semana 4: Programación dinámica (básica): Los peligros de la fuerza bruta. Principio de optimalidad de Bellman. Top-Down vs. Bottom-Up.
  • Semana 5: Programación dinámica (avanzada): Inicialización virtual. Máscaras de bits.
  • Semana 6: 1ra competencia y discusión.
  • Semana 7: Grafos (básico): Búsqueda en grafos. Flood fill. Árboles cobertores. Componentes conexas.
  • Semana 8: Grafos (avanzado): Máximo flujo, mínimo corte y apareamiento bipartito.
  • Semana 9: Cadenas de caracteres: Suffix trees. Tries. KMP. Expresiones regulares.
  • Semana 10: Consultas en árboles. Segment trees. BIT. RMQ. LCA.
  • Semana 11: Algoritmos aproximados y heurísticas. Primalidad. Coloración de Grafos. Geometría y probabilidades.
  • Semana 12: 2da competencia y discusión.  
Evaluación:
  • 10 Tareas - 5% cada una, para un total de 50%.
  • 1ra Competencia - 20%.
  • 2da Competencia - 30%.
(Nota: Las competencias no se evaluarán por posición alcanzada, sino por la aplicación de los conocimientos adquiridos a los problemas presentados y dinámica de equipo. Sin embargo, habrán puntos adicionales para los ganadores de cada una.)

Y esto concluye la descripción de la primera electiva hipotética. Estoy seguro que me faltaron cosas por incluir, así que cualquier comentario es bienvenido. Hasta una próxima entrada. :D

8 comentarios:

  1. Hola Ricardito! Muy buen post, suena muy interesante la electiva que propones!. A mi desde hace tiempo me gustaría ver algo así como Programación Orientada a Objectos Avanzada, algo así como Programación Funcional Avanzada. Porqué en lab. de algoritmos III vemos la introducción a POO, en lab. de lenguajes vemos mixins y en ing. de software vemos las buenas prácticas en el desarrollo de software; pero no existe una materia en la que un programador inexperto (como yo:D) pueda desarrollar sus habilidades en POO, con proyectos enfocados a éste fin. ¿Qué te parece?

    ResponderEliminar
    Respuestas
    1. ¡Épale José Luis! Gracias vale. :) Suena muy bien lo que planteas de una electiva que ahonde más en el pensamiento orientado a objetos y todo lo que ello implica en lenguajes, herramientas y diseño. En parte, la cadena de ingeniería de software se encarga de eso (ya que es el paradigma que han adoptado últimamente). Sin embargo, diseño orientado a objetos más allá de la clásica jerarquía de clases podría ser interesante. ¡Plantéalo! Estoy seguro que a más de uno le interesaría algo así. :D

      Eliminar
    2. Hay un problema con esa idea.

      Un curso de programación orientada a objetos que vaya a los fundamentos del concepto terminaría inevitablemente siendo un curso de programación funcional avanzada, si bien con contenidos diferentes de los que actualmente se cubren en el curso con ese nombre. Objects are a poor man’s closures:

      En realidad un curso con ese enfoque sería interesantísimo: experimentos en implantar modelos alternativos de cómputo en entornos inusuales. Montar sistemas de objetos sobre lenguajes funcionales es una experiencia muy grata e ilustrativa: hace que entiendas con precisión la esencia de la orientación a objetos. Personalmente, he experimentado enseñar el modelo de actores a estudiantes a través de sus proyectos de operativos en C (!), y fue impresionantemente efectivo! Varias veces se ha enfocado el laboratorio de lenguajes de programación I a esta idea: implantar un sistema de programación lógica en un lenguaje funcional, e implantar aspectos de lenguajes funcionales en un lenguaje lógico. Extender esa técnica pedagógica a más temas de la carrera sería valiosísimo.

      Por otra parte, es esencial tener en cuenta la naturaleza de lo que suele pasar por «orientación a objetos» en nuestra industria e incluso en porciones significativas del mundo académico de la computación. El creador del concepto de orientación a objetos, y el primero en usar el propio término, lo describe en . Una cita famosa atribuida a él (y consistente con su opinión documentada): «I made up the term “object-oriented”, and I can tell you I didn't have C++ in mind.»

      Orientación a objetos no tiene nada que ver con la basura que muchos cursos y muchos libros hacen pasar por orientación a objetos. Los famosos patrones de diseño, estudiados en textos tan absurdamente populares como el Design Patterns del “gang of four”, no son más que el resultado de modelar software en un sistema formal rígido e inexpresivo que es incapaz de representar directamente conceptos generales de orden superior que son necesarios para construir software en esos sistemas. Otros sistemas formales son mucho menos limitados: en particular, estas limitaciones de expresividad no existen en sistemas computacionales basados en los sistemas de tipos de Damas, Hindley y Milner (como ML y su numerosa descendencia, incluyendo a ya saben cuál lenguage genial), ni los basados en sistemas de tipos constructivos (como los usados en Agda, Idris, Coq y demás miembros de la familia de lenguajes con tipos dependientes). Todos ellos, claro, son lenguajes funcionales, y no debería sorprender: es indiscutible que las técnicas funcionales para construir software son las más expresivas conocidas, y muchos otros paradigmas no son más que especializaciones que pueden modelarse dentro de este esquema. La orientación a objetos nunca ha escapado de eso desde sus propios inicios.

      Un dato curioso es que los cursos de lógica y estructuras discretas ya trabajan con un sistema computacional que es en esencia funcional y de orden superior, solo que está disfrazado de un sistema lógico, y está del lado equivocado de la correspondencia Curry-Howard para que nos demos cuenta de que lo que aprendemos en esos cursos no es sino una forma de programación funcional. En lógica. Antes de algoritmos. Antes de programación imperativa. Mucho antes de (eso que se hace llamar) programación orientada a objetos. Solo es cuestión de conectar lo que se enseña al final con lo que se enseña al principio, y el tema de enseñar OO se volvería lo que siempre fue: una trivialidad, un truco divertido que se hace con clausuras.

      Eliminar
    3. …y Blogger se comió los links.

      Objects are a poor man’s closures: http://okmij.org/ftp/Scheme/oop-in-fp.txt

      Alan Kay —el inventor del concepto de orientación a objetos— explicando de qué se trata: http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en

      Eliminar
    4. ¡Excelente! Una clase entera resumida en un post, jajaja.

      Bueno, fíjate que la actual "programación funcional avanzada" se divide en dos partes. Primero, construcciones básicas (como Monads y morfismos) y luego el uso de Haskell en la vida real (casos de estudio, debuggers, profilers, etc.). La base teórica de la programación funcional es el lambda cálculo y la teoría de categorías. Esto sin embargo, no es el centro del curso, sino de uno que se daba en postgrado (la daba Pedro Borges y no la pude ver, por lo cual sufroo. XD)

      Una materia que reduce la orientación a objetos a una aplicación de clausuras de forma astuta es totalmente posible, ¡y sería interesantísimo! Pero quizá más para postgrado. Una versión de programación orientada a objetos avanzada para pregrado podría mencionarlo, pero más debería concentrarse en conceptos básicos (como clases, herencias, mixins, roles, etc) y sus usos en la vida real. Tareas en CLOS y Moose serían lo indicado, probablemente. Eso sería el equivalente a la materia de programación funcional avanzada que propone José Luis. :)

      Eliminar
    5. Perdón por la tardanza, no me había dado cuenta que me habían hecho más respuestas. Pues lo que yo estaba pensando va más enfocado en lo que escribió Ricardo. Porque durante toda la carrera he usado Python, Java (los patrones de diseño son un invento para hacer Java más pasable) y Ruby para POO, e innumerables veces he escuchado al Prof. Novich hablar de todos los defectos de estos lenguajes. Ahora siento que durante toda mi carrera he usado las heramientas incorrectas, pues quisiera ver una electiva que me permita aprender las herramientas correctas para la POO. Claro, habrá muchos problemas en los que será más adecuado usar un lenguaje funcional, pero me encantaría aprender las mejores técnicas para POO.

      Eliminar
  2. Epa chamo, me metí en el post luego de ver el titulo :P y al ver lo que propones (y de hecho, solo al ver el titulo) conecte con una materia que vi en la UCV llamada TAP (Técnicas Avanzadas en Programación), donde todos los ejercicios son problemas de maratones :P si puedes conseguirte el temario con tu hermano aprovecha para implementar algunas cosas de ahí :P

    ResponderEliminar
    Respuestas
    1. Épale man. Conozco de TAP y realmente se parece más a una cadena electiva que se da en la USB llamada "Diseño de Algoritmos" que aborda los problemas desde un punto de vista más teórico. Esta sería una materia más práctica, más al estilo del "Laboratorio de Programación Competitiva" que también tienen por allá en la UCV (la dió Hector hace poco). ¡Igual gracias por la recomendación! :)

      Eliminar