A.1. Estrategias.

Estrategias para entrenar

Está claro que para competir en un concurso, se debe entrenar primero. Por competir no debemos entender simplemente atender al evento, sino tener posibilidades reales de ganarlo. Y para ganar un concurso de nivel competitivo alto, no sólo hace falta entrenar, sino que hay que hacerlo de una manera disciplinada, constante y eficiente.

Al entrenar para un concurso de programación se deben practicar todos los aspectos involucrados. Se deben entrenar la velocidad a la que se resuelven los problemas, se deben estudiar algoritmos más comunes, hay que ir creando un formulario, foguearse en concurso en línea, estudiar estrategias, aprender a programar en papel, entre otros.

Existen varios puntos importantes de entrenar a través concursos en línea, y para poder aprovecharlos se deben tomar con una importancia similar a los concursos internos o regionales. Entre los aspectos más importantes se encuentran: Por los horarios de los concursos en línea, a veces es complicado poder participar en tiempo real. Aún así, generalmente es posible conseguir los problemas después de que se realizaron. En páginas como la de Saratov es posible participar en un concurso “virtual” donde puedes ver que lugar obtendrían en caso de haber participado durante el concurso; o en la de Tianjin, en la que se pueden escoger problemas para realizar un concurso virtual en cualquier momento. También son útiles las páginas como el World Archive en donde se pueden escoger problemas regionales, con lo que se pueden comparar los resultados con los de los equipos que participaron ese año. Utilizar diversas páginas puede servir para entrenar en distintos tipos de problemas.

Al igual que en las competencias deportivas, los entrenamientos deben procurar ser continuos y planeados. Sobre-entrenar poco antes de los concursos generalmente no es aprovechable y puede llegar a ser contraproducente. Idealmente, se deben entrenar dos o tres horas diarias entre semana, aprovechando los fines de semana para concursos en línea y para investigar nuevos algoritmos.

Algo paradójico es que durante un concurso no se debe pensar mucho. Si alguien se encuentra bien preparado, al momento de competir ya está plenamente familiarizado con todos los aspectos que se pueden presentar. Obviamente, es imposible predecir todo lo que va a acontecer durante el concurso, pero entre más cosas se puedan dar por resueltas de antemano, más tiempo se tiene para pensar en el resto.

El aspecto más importante para tener que pensar menos es la experiencia, pero en ocasiones es difícil poder recordar todo lo que se ha entrenado. Para esto se debe utilizar el formulario, donde lo más conveniente es contar con los algoritmos más importantes, complementados con una breve descripción de lo que hacen, cuales son sus entradas, sus salidas y su complejidad.

Es importante notar que el formulario debe ser un complemento a la experiencia, y no un sustituto. No sirve de mucho tener el algoritmo que necesitas cuando no sabes como funciona. Generalmente, en un concurso no hay problemas que se resuelvan exactamente igual al del formulario, por lo que o se tiene que empezar el problema desde cero, o se tiene que adaptar un algoritmo del formulario. Por trivial que sea la modificación, como puede ser un cambio en la inicialización de las variables, al no conocer el funcionamiento del código, no es posible realizarlo. Durante el concurso no es momento para aprender como funcionan los algoritmos.

Existen tres puntos clave al momento de concursar, los cuales son: tener conocimiento pleno de los algoritmos requeridos y la habilidad para aplicarlos a los problemas, poder codificar y debugear correctamente, y aprovechar al máximo los tres integrantes del equipo.

Una vez que se tiene un conocimiento amplio en algoritmia y programación, poder mejorar en estos ámbitos se vuelve cada vez más tardado y complicado, por lo que se llega al punto donde conseguir acoplarse como equipo puede ser lo que defina el lograr mejores lugares.

Al trabajar en equipo es necesario tener una estrategia planeada y tratar de seguirla. Al momento de planear la estrategia se deben tomar en cuenta las características de cada miembro. Aunque se espera que los tres miembros tengan un entendimiento, aunque sea básico, de los temas más importantes de algoritmia y programación, cada uno va a tener preferencias y aptitudes hacia algún tipo específico de problemas. Conocer esto ayuda a saber en que forma se van a repartir los problemas, como se va a acomodar el equipo y que temas son convenientes entrenar individualmente.

A parte de conocer las fortalezas y debilidades de cada quien como programadores, también es importante tener un entendimiento a nivel personal. Muchas veces los equipos inexpertos tienden a perder el tiempo por no tener la confianza como para ponerse a discutir la forma en que se deben resolver los problemas o para definir la estrategia a seguir, mientras que también existen los casos opuestos en que miembros del equipo entran en conflicto y no tienen la experiencia como para poder resolverlos de forma rápida y eficiente.

Algo importante es que la estrategia es algo dinámico que se va perfeccionando a través de la práctica. Poniéndola en uso solamente durante los concursos regionales no se puede llegar al refinamiento necesario. Se debe tomar en cuenta la mayor cantidad de variables posibles, desde como acomodar los formularios y demás material, pasando por la forma en que se repartirán los problemas y cuales se atacarán primero, hasta saber la forma en que se resolverán los inconvenientes (como cuando una solución no es aceptada) y poder acoplar la estrategia a la situaciones que se presenten durante el concurso.

Además de contar con un formulario, también puede ser útil contar con una lista de posibles fallas. De manera similar al formulario, son detalles que se van adquiriendo con el correr del tiempo, principalmente a través de tropiezos propios, y que en momentos de presión puede ser útil tenerlos impresos. En esta lista se pueden incluir cosas como especificaciones del compilador y fallas conocidas,  problemas que hayan tenido concursantes en ediciones anteriores, errores comunes por lo que problemas resultan no aceptados, entre otras. Sobre el último punto, se incluyen algunas recomendaciones al respecto posteriormente en esta misma sección.

Para poder estar en óptimas condiciones para el concurso, se necesita estar leyendo continuamente libros de programación, estructuras de datos y matemáticas, para mejorar la capacidad de resolución de problemas. También es conveniente leer ocasionalmente libros que puedan ayudar a crear mejores estrategias, como lo puede ser libros de ingeniería industrial (optimización de recursos) y de filosofía (como el arte de la guerra). Por último, también existen factores como la alimentación y el ejercicio, en los que es difícil dar una estrategia porque son aspectos que varían de persona a persona, pero que es importante notar es que para tener un óptimo rendimiento mental, se debe tener una buena salud física.

Es probable que la capacidad innata de las personas en distintas partes del mundo se distribuya de manera similar. Si en países como Rusia y China hay tantos buenos programadores, no necesariamente todos son más inteligentes que los mexicanos, sino que se tienen mejores métodos de aprendizaje y una preparación más amplia.


Estrategias para concursar

Antes de que inicie el concurso es recomendable contar con todos los elementos necesarios y situarlos de forma que sean accesibles sin que lleguen a estorbar. Lo más importante es tener el formulario acomodado, siendo también recomendable llevar papel en blanco, papel para graficar, lápices y marcadores. Aunque en el concurso existe un área de refrigerios, es recomendable también llevar comida por cuenta propia, principalmente chocolate negro y nueces (o similares), que proporcionan energía a corto plazo para pensar mejor.

Aunque en el mundial y en algunos regionales (cada vez más), ya no es posible ingresar libros, en caso de estar en un concurso que si lo permita, también se debe buscar la forma de ubicarlos. Libros que pueden resultar útiles son de programación, de matemáticas (teoría de números, análisis numérico, probabilidad, de fórmulas, etc.), de algoritmos (como el Cormen o el Sedgewick) y un diccionario inglés-español.

Una vez que inicia el concurso, dos miembros pueden ir leyendo los problemas mientras que el tercero crea todos los archivos *.pas o *.c, y copia todos los ejemplos de entrada a sus respectivos *.txt. Una vez que los dos primeros terminan de leer, le pasan al que está en la computadora todos los algoritmos que creen que van a utilizar para que los vaya capturando. Mientras, los otros dos clasifican los problemas por dificultad. Si se dan cuenta que un problema se puede resolver rápidamente (generalmente hay uno o dos de consolación, o alguno que salga directo del formulario), el de la computadora puede ir resolviéndolo.

Al crear los *.pas o *.c, se pueden ir incluyendo datos que sean comunes en la mayoría de los problemas. Por ejemplo:




Una vez hechos el o los problemas inmediatos, el que estaba de capturista puede ponerse a leer los problemas. En cuanto los tres miembros han leído todos los problemas, estos se deben ordenar por dificultad y se les puede asignar una respuesta tentativa.

Dado que el tiempo es un factor determinante en este tipo de concursos, todos los competidores intentan resolver cualquier problema lo más rápido posible. Esto hace que se presionen y lean superficialmente los problemas, o inclusive, que intenten adivinar lo que preguntan. No leer cuidadosamente conduce a errores de interpretación, a saltarse problemas fáciles, a no entender detalles del problema que pueden cambiar la dificultad del mismo, entre otros.

Antes de empezar con cualquier problema, es mejor tomarse unos cuantos minutos para entender el problema en su totalidad. No es conveniente dejar a la suposición o a la casualidad. Mientras el problema no lo especifique, no se puede dar algo por hecho. Si surge cualquier duda en la descripción de algún problema, es conveniente preguntársela a los jueces desde el principio aunque no se tenga contemplado resolver el problema. También es útil marcar o subrayar toda la información importante al momento de leer el problema, sobre todo las entradas y salidas (variables, formato y rango).

Después de leídos los problemas, estos se reparten según las aptitudes de los integrantes y la estrategia que se haya acordado antes. Independientemente de cómo se hayan repartido los problemas, al momento de solucionarlos se deben tomar en cuenta los siguientes factores.

Sobre el uso eficiente de la computadora:

Sobre como encontrar una solución:

Sobre como codificar la solución:

Probablemente, la parte de mayor estrategia durante el concurso es escoger cuales problemas resolver, en que orden y en que momento. De acuerdo a estas decisiones, el equipo puede terminar con varios problemas casi resueltos, pero ninguno aceptado, o con varios aceptados pero sin tiempo para continuar en los demás. Fabian Ernst, Jeroen Moelands y Seppo Pieterse, quienes fueron competidores mundialistas hace ya varios años, dan tres estrategias básicas que se pueden seguir:

1.- Cada quien por su cuenta. En la primera estrategia, la idea básica es, una vez que los problemas están separados por dificultad, empezar por los más sencillos y dejar que cada integrante del equipo trabaje sólo en el problema que se adapte a sus gustos o aptitudes. Una vez que un problema es aceptado, se toma otro y se continúa.

Esta estrategia tiene la ventaja de que los problemas más simples son resueltos rápidamente, pero deja muy poco tiempo para resolver los complejos. También tiene el inconveniente de que al estar resolviendo problemas de la misma dificultad, los integrantes necesitarán utilizar la computadora más o menos en los mismos tiempos. Es una buena estrategia para equipos principiantes o para quienes no les interesa definir una estrategia.

2.- El capturista. Se elige a un miembro del equipo para que utilice la computadora, mientras los demás resuelven los problemas. El que está en la computadora es el encargado de escribir todos los programas. Mientras los otros dos miembros están programando el código en papel, el capturista se encarga de las rutinas de lectura y escritura, capturar los programas terminados y hacer debugeo sencillo.

Esta estrategia es útil cuando un miembro del equipo es rápido para teclear y conoce a fondo el lenguaje de programación, mientras los otros dos son buenos para resolver problemas. Tiene la desventaja de que el capturista no es aprovechado para resolver problemas. Una variante pudiera ser cambiar de capturista después de algunas horas, cuando algún miembro de equipo esté cansado.

3.- Pensamiento en grupo (Think Tank). En esta última estrategia, dos personas examinan juntos todos los problemas mientras el tercero captura lo básico y resuelve los problemas inmediatos. Primero se buscan los problemas simples, los cuales se los explican al tercer miembro. Una vez hecho esto, analizan cuidadosamente el resto de los problemas y deciden como los van a resolver. Cada vez que un programa es rechazado, si no se encuentra rápidamente donde está el error, se guarda para después. A las tres horas y media, se analiza la situación actual del equipo, y se determina la estrategia a seguir. A partir de entonces, se procura no tener que empezar nuevos códigos, sino terminar los ya existentes. La persona que resolvió los problemas fáciles puede estar creando entradas, mientras los otros dos revisan y corrigen los códigos.

De esta forma, los problemas difíciles pueden ser atacados desde el principio del concurso por dos personas, mientras que el tercero resuelve los fáciles, con lo que se tienen mejores oportunidades de terminar más códigos. Tiene la desventaja de que el tiempo total no será bueno, por lo que para ganar se tendrán que resolver más problemas. Si al principio o a mediados del concurso no se está entre los primeros lugares, no hay que sucumbir al pánico, simplemente hay que enfocarse a obtener los problemas que pueden resolverse.

Cual estrategia escoger va a depender en gran medida de las características del equipo y de la experiencia que tengan trabajando juntos. Aún así, siempre es conveniente ir ajustando la estrategia de acuerdo a como se desarrolle el concurso, principalmente observando los problemas que están siendo resueltos. Independientemente de la situación, es importante siempre confiar en las capacidades de los demás y buscar la forma en que puedan trabajar de forma óptima. Y sobre todo, si durante un concurso nos encontramos en una situación desfavorable, debemos recordar que la culpa no es de la silla.


Estrategias para “debugear” (“Trouble shooting” o Búsqueda de errores)

Es inevitable que durante un concurso (ya sea en línea o presencial), alguna solución falle. Seguramente la solución parece correcta (sino, ¿para que mandarla?), y teniendo encima la presión del tiempo, se vuelve complicado encontrar el error. Por esto, se debe estar preparado para saber como responder ante tal situación.

Una buena forma de buscar es utilizando una lista de posibles fallas. Con el paso del tiempo (y entrenando), muy posiblemente la lista se vuelva innecesaria, pero es común que durante el concurso obviemos o se nos olviden datos importantes. Con la limitante de hojas que se pueden ingresar como formulario, pudiera parecer un desperdicio de espacio, pero es probable que resulte útil.

A continuación tenemos una lista de errores comunes. Se presentan de forma seguida y con explicaciones para poder analizarlos, pero lo más recomendable al concursar es tener la lista separada por categorías (y subcategorías), si es necesario), tener una sublista de posibles soluciones, y hacerla lo más compacto posible.
            Por último, hay que recordar que aunque el concurso haya sido preparado a conciencia, puede haber fallos humanos (y con mucha mayor razón cuando se hacen improvisados, como comúnmente pasa en México). Existe la posibilidad de que el “Wrong Answer” no sea problema ni del algoritmo ni del código sino del juez (ya ha pasado), por lo que no hay que enfrascarse en el problema, y si estás seguro de que está bien (y aunque no estés tan seguro), es conveniente volver mandarlo al final, y con suerte lo revisa otro juez de forma correcta. Problemas no resueltos no generan penalización, así que no hay mucho que perder.




© Pier Paolo Guillen Hernandez
World of πer