En el curso de Programación II los estudiantes resuelven problemas usando un juez automático en línea. Estos problemas han sido construidos por el profesor, asistentes, y otros estudiantes previos del curso. De la misma forma, los estudiantes activos de Programación II podrán proponer nuevos problemas, a los cuales se les llama problemas inventados y recibir crédito extra por un máximo de 2% en la nota final del curso.

Temas de los problemas

Los problemas en el curso se clasifican en secciones temáticas de acuerdo al paradigma de programación, como se muestra en la tabla de abajo. La cantidad de puntos que el problema inventado recibirá se indica en la columna "Puntaje" de la tabla siguiente, y dependerá de la sección en la que se clasifique. Si un estudiante plantea varios problemas, se sumarán los puntajes de cada uno de ellos.

Paradigma Sección Tema Puntaje

Programación procedimental
Metaprogramación

1.1

Entrada y salida

0.1

1.2

Expresiones y condicionales

0.2

1.3

Repetición: Ciclos

0.3

1.4

Subrutinas

0.4

1.5

Indirección, arreglos y matrices

0.5

1.6

Cadenas de caracteres

0.5

1.7

Registros de memoria

0.8

1.8

Recursión

1.0

Programación orientada a objetos

2.1

Clases, objetos, atributos, métodos

1.0

2.2

Sobrecarga de operadores

1.0

Programación genérica

3.1

Arreglo dinámico

1.0

3.2

Listas enlazadas

1.0

3.3

Árboles

1.0

Programación orientada a objetos

4.0

Herencia y polimorfismo

2.0

El estudiante que desee plantear un problema para una sección que se está viendo en el curso, debe hacerlo a más tardar dos semanas después de que la sección se ha cubierto en el curso. Esto es con el fin de que los ejercicios inventados no se acumulen al final del ciclo lectivo.

La creación de problemas correlaciona con una mayor comprensión de los conceptos de programación, de acuerdo a la literatura científica. Para crearlos, el estudiante debe prestar atención a los conceptos de programación involucrados en la sección a la que pertenecerá el problema inventado. Puede tomar como ejemplo los problemas que resuelve en el juez automático en línea (HackerRank).

Los ejercicios inventados deben ser únicos entre estudiantes. Es decir, si dos o más estudiantes proponen el mismo ejercicio, se dará crédito sólo al primero en someterlo. El profesor servirá como el ente centralizador de los ejercicios inventados por estudiantes, y podrá ayudarles en el proceso de creación de los mismos durante las horas de consulta.

Procedimiento para plantear problemas

  1. Una vez que tenga una idea de problema, descargue la plantilla (ver la siguiente sección), extráiga en una carpeta inventados/nombre_del_problema/ en su repositorio personal de control de versiones para el curso.

  2. Edite el archivo problem.es.md y resuma su idea en al menos un párrafo.

  3. Escriba un ejemplo de entrada y salida en el mismo archivo problem.es.md. Este paso es importante para poder tener una idea más clara del problema antes de discutirlo con el profesor.

  4. Contacte personalmente al profesor (preferiblemente) o diríajele un correo indicando dónde se encuentra el problema dentro de su repositorio de control de versiones.

  5. El profesor le indicará si ya se tiene un problema idéntico o similar, y en tal caso le brindará instrucciones para modificarlo o plantear otro.

  6. Si el profesor acepta la propuesta del problema, le indicará la sección a la que pertenece. En tal caso continúe con la construcción del mismo siguiendo las sugerencias que le hayan brindado. Amplíe la descripción del problema, cree más casos de prueba, implemente una solución, documente la solución, y cree aún más casos de prueba, como se indica en la sección siguiente de este documento.

  7. Escriba un correo electrónico al profesor avisando que el problema está disponible en su repositorio de control de versiones.

  8. Si el profesor solicita correcciones, realícelas y responda al correo indicando cuando está listo.

  9. Cuando la respuesta del profesor indique que el ejercicio está completo, obtendrá los puntos de la sección donde se haya ubicado.

Formato de los problemas

Cada problema inventado debe tener un formato influenciado por la programación competitiva y que facilita su adaptación a un juez automático en línea. Las siguientes plantillas proveen archivos que facilitan la elaboración de un problema para estas herramientas, de acuerdo al lenguaje de programación a usar: C o C++.

box c
Plantilla problema inventado en C

box cpp
Plantilla problema inventado en C++

Para presentar los problemas inventados, descargue uno de los archivos comprimidos anteriores, acorde al lenguaje de programación que se va a usar para resolverlo. Luego siga estas instrucciones:

  1. Descomprima el archivo que descargó en una carpeta inventados/ de su repositorio de control de versiones personal para el curso.

  2. Obtendrá una carpeta con los archivos extraídos. Renombre la carpeta para incluir el número de la sección a la cual pertenecerá el problema y algún texto corto alusivo al problema. Por ejemplo, si el problema a resolver es un validador de jugadas de ajedrez en el tema de matrices (1.5), podría usar un nombre como inventados/1.5-validador_ajedrez para la carpeta del problema en su repositorio de control de versiones.

  3. Edite el archivo problem.es.md para escribir el enunciado de su problema en notación Markdown. Ubique el problema en un contexto: una situación hipotética pero realista que haga al problema aplicado y más interesante. El enunciado del problema debe incluir un ejemplo de entrada que recibirán los programas que intenten resolverlo, y su correspondiente salida esperada.

  4. Escriba el caso de prueba de ejemplo. Copie el caso de prueba que incluyó en el enunciado del problema (en problem.es.md) en dos archivos: input000.txt para la entrada y ouput000.txt para la salida correspondiente.

  5. Agregue al menos dos casos de prueba más, y por tanto, al menos dos parejas de archivos: (input001.txt, output001.txt) y (input002.txt, output002.txt). Piense en valores interesantes, extremos o inválidos a probar. Por ejemplo, un programa para encontrar números primos puede probarse con números negativos, 0, 1 (que no es primo), 2 (el único primo par), y valores muy grandes que pueden hacer fallar por exceso de tiempo para una solución fuerza bruta.

  6. Solucione el problema. Escriba su solución en el archivo solution.c o solution.cpp acorde al lenguaje de programación (C ó C++ respectivamente). Puede usar el editor de texto de su elección, o un IDE como QtCreator. La plantilla provee el proyecto solution.pro para QtCreator.

  7. Compile su solución. Si no usa un IDE, puede aprovechar el script px provisto que viene con la plantilla. Para compilar, basta llamar a este script en línea de comandos sin parámetros: ./px.

  8. Pruebe su solución contra los casos de prueba. Para probar un caso de prueba particular invoque su ejecutable con la pareja de archivos de entrada y salida y verifique que coinciden. Por ejemplo, si al invocar ./solution < input001.txt | diff output001.txt - no se producir salida alguna, su programa pasará el caso de prueba. Si quiere probar su solución contra todos los casos de prueba puede invocar ./px test.

  9. Agregue más casos de prueba. Puede aprovechar su solución para acelerar este proceso. Cree simplemente el archivo inputXXX.txt del nuevo caso de prueba. Luego use su solución para generar la salida esperada correspondiente, por ejemplo: ./solution < inputXXX.txt > outputXXX.txt. Si quiere generar o actualizar los correspondientes outputXXX.txt a partir de los archivos de entrada puede emitir ./px output. Este comando debe usarse con mucho cuidado, pues sobrescribe todos los archivos outputXXX.txt con la salida que genera su solución.

  10. Este paso es opcional. Si el profesor le indica que el problema lo requiere, modifique el archivo given.c ó given.cpp y escriba el código fuente inicial que dispondrán las personas que resolverán su problema inventado. Es un extracto de su solución (solution.c o solution.cpp) que puede ayudar a futuros estudiantes a concentrarse en ciertas partes del código, corregir un error inducido en el código fuente, o imponer un trozo de código que no se puede modificar. Por ejemplo, puede proveer una función main() completa y pedir a quienes ressolverán el problema escribir otras funciones faltantes. O bien, proveer varias funciones y que ellos tengan que implementar el main() u otras funciones, o proveer una clase incompleta, o una clase que depende de otra que está ausente…​