Quiero empezar este post dando las gracias a Wastl que fue el que tuvo la idea original de crear un advent of code allá por 2015, que muchos le han copiado después, y que él es la única persona que mantiene el proyecto.
Web del proyecto: https://adventofcode.com/
Introducción
1 - Qué es AdventOfCode?
Advent of code no son más que unos retos de programación que se hacen en el mes de diciembre con motivo de la festividad de navidades.
Es similar al calendario de adviento de toda la vida, pero con código.
Hay que decir que las pruebas son complicadas, bueno, para niveles juniors son bastante complicadas, no por el código en sí, sino porque cada prueba tiene una descripción de casos en el “mundo real” (suelen ser problemas que tienen los elfos para ayudar a papa noel). Lo que hace que sea complicado, ya que algunos detalles se pueden obviar, o los podemos pasar por alto.
Personalmente utilizo alrededor de una hora en hacer cada test.
Nota: los test son en inglés
2 - ¿Por qué deberías realizar AdventOfCode?
En mi opinión hay que realizarlo porque son tests muy entretenidos, la comunidad está muy involucrada en hacerlos, hay grupos y foros por medio internet comentando las soluciones y cómo hacerlo mejor, o de una forma o de otra. Pero los dos motivos principales para mi son los siguientes:
- Es una forma de adentrarte en otro lenguaje. Lo que mucha gente hace es, cada año, los test los realizan en un lenguaje de programación distinto, este año puede ser C#, al siguiente, puede ser JavaScript, el otro PHP, etc. Así da para adentrarse y aprender un nivel básico de cada lenguaje.
- Te puede servir para ganar conocimiento avanzado de Arrays. Si bien es cierto que la gran mayoría de problemas se pueden solucionar sin el uso de conocimientos avanzados, el tener estos conocimientos te ayuda a hacer el código más corto;
Por ejemplo hay una serie de personas que se dedican a solventar todos los ejercicios con “una instrucción”, esto se consigue en C# a través de utilizar LINQ. Y créeme que necesitas mucho conocimiento de LINQ para poder hacerlos en una única línea.
3 - Ejecución de Advent Of Code en C#
Se que es un poco tarde en el evento, de hecho, solo quedan 4 días para el final del mismo, pero el año que viene quiero hacerlo en C# ya que este año lo que he hecho, ha sido en ruby (7 días) y siempre tenía el problema de que no había ninguna librería que me hiciera la vida más fácil. Y no quiero que para C# sea lo mismo.
Para ello he creado la librería Netmentor.AdventOfcode
Disponible en GitHub y en Nuget, con la que la vida se facilita un poco.
Esta librería consiste principalmente en una clase abstracta llamada AoCSolution
la cual tiene una serie de constructores y dos métodos.
Los métodos son:
string Part1()
string Part2()
Representando las dos partes que tiene cada problema de AdventOfCode.
Y después tenemos múltiples constructores que nos facilitarán la vida a la hora de inicializar los problemas.
El formato de los constructores es el siguiente:
protected AoCSolution(string path, string filename = "input.txt")
protected AoCSolution(int year, int day, string filename = "input.txt")
protected AoCSolution(string path, AoCFileType type = AoCFileType.Input)
protected AoCSolution(int year, int day, AoCFileType type = AoCFileType.Input)
AoCFiletype
es básicamente un enum que acepta `AoCFileType.Input
` y AoCFiletype.Test
.
Esto es debido a que es un estándar dentro de los usuarios de AdventOfCode tener el fichero input.txt
con los datos que nos da el sistema y algunas personas (entre las que me incluyo) utilizan el fichero de test para probar el algoritmo con menos datos y que sea mas fácil debuguear.
Además si elegimos la opción año y día estaremos utilizando la ruta relativa para coger los ficheros con 2022/01
(para el año 2022 y el día 1) También un estándar entre los usuarios de AdventOfCode.
Finalmente, el contenido de nuestro fichero queda cargado en la variable Input
.
Para utilizar la librerÍa simplemente creamos una clase e implementamos la clase abstracta:
public class Day01 : AoCSolution
{
public Day01(AoCFileType filetype) : base(2022, 01, filetype)
{
}
public override string Part1()
{
return Input.....;
}
public override string Part2()
{
throw new NotImplementedException();
}
}
Y lo que tenemos que hacer es ya bien sea un test una aplicación de consola, etc. En mi caso lo hago con tests y así sería la forma de implementar dicho test.
[Fact]
public void ResolveDay1()
{
Day01 day01 = new Day01(AoCFileType.Input);
string result1 = day01.Part1();
Assert.Equal("10130", result1);
string result2 = day01.Part2();
Assert.Equal("10005", result2);
}
Y este sería un ejemplo de la estructura de carpetas: