Advent of Code 2022
Falta apenas una semana para Advent of Code, por lo que he decidido crear este hilo para invitaros a participar.
¿Qué es Advent of Code?
Advent of Code es un evento de programación/resolución de puzzles cuyo funcionamiento es como el de un calendario de adviento.
Desde el día 1 hasta el 25 de diciembre se libera un nuevo puzzle de programación que te va contando una historia. Te pedirán una respuesta (habitualmente numérica o una cadena) al problema que se plantea en base a unos datos de entrada.
Cada problema consta siempre de 2 partes a resolver.
¿Qué se necesita para participar?
Únicamente necesitas registrarte en la web.
Puedes usar el lenguaje de programación que prefieras (incluso puedes usar papel y lápiz o una excel).
¿Cuál es el objetivo?
De cara a los leaderboards solo importa conseguir el resultado correcto en el menor tiempo posible. Lo limpia o sucia que sea la solución o la eficiencia del algoritmo da igual.
No obstante, al margen del leaderboard, el objetivo puede ser algo muy subjetivo:
- Habrá quien prefiera resolver cada problema lo más rápido posible.
- Otros preferirán hacer el algoritmo más eficiente posible.
- También puede que desees poner en práctica algoritmos o patrones de diseño que conozcas o que estés aprendiendo.
- ¡Incluso hay gente que luego hace animaciones con Javascript/Unity/un simple terminal para representar la resolución del problema de manera gráfica! Incluso hubo alguien que decidió resolver un problema usando Factorio
¿Cuándo se libera cada problema?
Cada día a las 00:00 EST/UTC-5, 6:00 hora española, una hora menos en Canarias:

¿Es muy difícil?
La dificultad de Advent of Code va subiendo progresivamente según avanza el evento.
Los primeros días casi todo el mundo puede resolver los problemas. Conforme pasan los días, estos son cada vez más duros y va haciendo falta más conocimientos de distinta índole para progresar.
¿Hay tiempo límite para resolver cada puzzle?
No. Si algún día te bloqueas, puedes resolverlo más adelante sin ningún problema.
¡Incluso puedes probar a resolver puzzles de años pasados para ir entrenando!
Leaderboards privados
Una vez registrado, si usas el siguiente código en esta página, podéis uniros a este leaderboard privado con otros usuarios de Gamersmafia para ir comparando vuestro progreso:
1552540-76b02474
Más info: advent of code - about
PD: El año pasado participé por primera vez y me lo pasé muy bien, os lo recomiendo.
Hf & gl! 
-
Desarrollo
- General
Desarrollo
Gracias Flash. Voy a estar de viaje parte de diciembre, pero si avisas aquí cuando empiece prometo hacer al menos un puzzle. :-)
claro! avisaré por aquí
Faltan apenas 12h y media!!
guiño guiño, codo codo, patada voladora
5 minutos!!
¿Qué representa el primer campo después de 1), 2)? ¿El número de intentos?
Parte 1
Parte 2
es una puntuación que se da en función de las personas que haya en el leaderboard y cuanto tardas en resolver el puzzle. Se calcula mas o menos asi:
Si hay 2 personas, el primero que resuelve una de las dos partes se lleva 2 puntos, el segundo 1 punto. Como ahora mismo solo somos dos, y yo he resuelto primero parte a y parte b, pues en total yo me he llevado 4.
El número de puntos aumenta por cada persona que haya en el leaderboard hasta un máximo de 100. es decir, si hay 100 personas, el primero en solucionar se lleva 100 puntos, el último 1, el 101 se lleva 0. Se ajusta automáticamente si alguien entra en el leaderboard. es decir, yo tengo 4 puntos ahora, pero si entra alguien que ha tardado mas que yo en resolver, yo paso a tener 6 puntos y lo mismo pasaría con tus puntos.
Mi algoritmo (está ajustado para que funcione tanto para parte A como B):
¡Qué elegante es tu código!
Entendido, gracias. :-) ¡A ver si se anima alguien más!
Creo que es más Ruby que yo. Está diseñado para ser bello, en palabras de su autor.
ojalá se apunte más gente al leaderboard si! además mola poder comparar soluciones!
El día 2 primero lo he resuelto con un churro de código muy feo, y luego me he puesto a limpiarlo a ver que podía hacer.
Análisis del problema
Me he dado cuenta de que en vez de resolver el churro como lo hice inicialmente con un montón de switches, en realidad podía convertirlo todo a una matriz de resultados.
Para el problema A:
Para el problema B:
Una vez visto esto, vi claro que el esqueleto del algoritmo es igual en ambos casos y que solo cambia el peso de cada jugada.
Solución
Igual es un poco over-engineered, pero me gusta tratar de aplicar patrones de diseño en los puzzles mas sencillos (se prestan a experimentar con ellos).
En este caso he optado por Strategy Pattern mezclado con Template Method (en realidad es más lo segundo que lo primero).
RockPaperScissorsStrategy
Esta clase abstracta contiene una lógica que es común para ambos puzzles:
El constructor convierte los datos del fichero a un listado de rondas. En cada ronda guardo el índice de la jugada, de tal forma que por parte del elfo
R=0,P=1yS=2y por mi parteX=0,Y=1yZ=2El método
solve()llama primero a un método abstractoinitializeResultMatrix()que cada estrategia inicializará de la manera que le corresponda. A continuación recorre todas las rondas y va sumando los resultados en función de matriz de resultados.Round
Simplemente guarda el índice de la jugada a seleccionar en la matriz de resultados:
Finalmente, solo queda crear dos estrategias diferentes, cargando en cada una su matriz de resultados:
RockPaperScissorsBasicStrategy
RockPaperScissorsAdvancedStrategy
Conclusiones
solve()el array de pesos, pero a cambio implicaría meter checkeos para verificar que el array que me pasan es un array 3x3 válido.Depende de tu objetivo con este problema: ¿Es encontrar una solución con menos caracteres? ¿Es minimizar complejidad? ¿Es escribir código fácil de modificar sin introducir bugs? ¿Es aplicar patrones de diseño sea como sea?
Mi “thought process” con la primera parte ha sido: hay 9 combinaciones, la complejidad está en traducir A, B, C, e X, Y, Z a lo que representan, necesito enumerar los casos, son pocos, voy a traducirlo a código. Al escribir el código no se me han ocurrido soluciones obvias para comprimir las 9 nueve líneas de score_per_result y dado que esto es write-once code lo he dejado así.
Al leer la segunda parte he entendido que podía darle la vuelta a la primera solución y es lo que he hecho.
Tenía un 85% de confianza de que ambas soluciones fuesen a dar la solución correcta a la primera y el hecho de que la han dado para mí valida la elección de optimizar para código fácil, para mí, de mantener.
Primera parte
Segunda parte
Había escrito un comentario enorme explicando días 3, 4 y 5 but…

Así que me limitaré a dejar por aquí mis resoluciones:
El de hoy (día 06) ha sido demasiado sencillo, miedo me da lo que nos vayan a poner mañana:
Para la parte 1,
expectedMarkerSizedebe valer4y para la parte 2,14.El día 7 ha sido uno de los que más me ha gustado en lo que va de año.
Me he creado una clase que permite modelar lol que es un fichero:
https://github.com/Flashky/advent-of-code-2022/blob/master/src/main/java/com/adventofcode/flashk/day07/File.java
Y luego la clase que parsea los datos de entrada para construir un árbol de directorios y ficheros y evaluar las respuestas:
https://github.com/Flashky/advent-of-code-2022/blob/master/src/main/java/com/adventofcode/flashk/day07/DeviceSpace.java
Estoy quedándome atrás, Flash, por lo que te comenté el otro día por chat, pero sigo leyendo tus entradas e intentaré ponerme al día. :-)
sin problema! disfruta de las vacaciones! ten en cuenta que advent of code se puede hacer en cualquier momento, incluso cuando ha finalizado el evento. Yo estos días de puente tampoco estoy teniendo demasiado tiempo para pasarme por aquí.
Oh, eso me deja más tranquilo, gracias. :-)