El parser: secuencia de parsers "polymerP" y "newlineP >> rulesP" que capturan tanto la plantilla como las reglas. Creamos todos los subparser necesarios. Leed la función desde el final hacia arriba y veréis la "estructura"
la parte 1 "del tirón". Leemos las reglas y preparamos un diccionario.. BB -> C. En cada paso de polimerización convertimos el pólimero en pares(zip) y aplicamos la conversión a cada par según el dict. El resultado crece rápidamente por lo que abreviamos la salida si len > 60
Despues contamos cada letra guardando las cifras en un dict "stats". Convertimos "stats" a lista de tuplas (k, v) y ordenamos usando como criterio el segundo valor de cada tupla mediante itemgetter (traido de operator)
Finalmente calculamos la clave mas común menos las mas rara..
Probamos el fichero de test..
Y seguidamente el puzzle..
Ha sido fácil (lo bueno vienen después!)
En la segunda parte nos piden básicamente el mismo cálculo pero en el paso 40. rápidamente vemos que no va a ser tan facil ya que el poliméro crece desmesuradamente..
Tras lo cual vemos que un acercamiento tipo "Lanter fish" nos permitirá atacar el problema. Si tenemos una regla BH -> C en realidad podemos escribirla como BH -> BC, CH
como las reglas no se solapan contando la poblacion de cada "par" generado ¿podríamos llevar la cuenta?
El problema es que si nos atenemos a la cardinalidad de las letras BH -> C no es BH = BC + CB sino mas bien BH = BC + CB - C ya que la letra se intercala dos veces (una por cada par generado). por tanto debemos llevar la cuenta de los excesos generados al aplicar cada regla..
Empezamos construyendo el dict de reglas: Ahora una reglas como BH -> C se codifica como ruleset["BH"] = [("BC", 1), ("CH", 1), ("C", 1)] es decir una lista de cambios que indica añadir 1 instancia de cada par y una instancia de una letra de exceso.
Los pares van a ir al diccionario de pares y los excesos iran a un diccionario de excesos (¡que original!) para cada elemento generado se contabiliza un 0 en su dict respectivo "para hacer hueco". Finalmente devolvemos los 3 dict en una tupla.
Estraemos los pares inciales de la plantilla y sus letras de exceso es decir: NNCB se convierte en NN, NC, CB y esta conversion genera N, C caracteres de exceso. Estos valores se colocan en los diccionarios de pares y excesos como estado incial antes de iterar la "polimerización"
En cada paso se iteran sobre los pares existentes en el dict "pairs" se obtiene su lista de cambios de ruleset[pair] se ajusta estos cambios en funcion de cuantos pares hay 1 , 2 ó 53000.. se elimina ese "par" del dict pares (restando uno).
La lista de cambios indica cuantos instancias hay que añadir de los nuevos pares resultantes (recuerda BH -> BC, CH) y se contabilizan los elementos en exceso resultantes (en este caso C)
Finalmente tras iterar las 40 veces, contamos el numero de letras destructurando cada par del dict "pares" y sumando las letras cada uno con la suya y restando los excesos que estan consignados en el dict elements.
Finalmente el dict stats es convertido en una lista de tuplas y reordenadas estas por su segundo valor de forma descendente usando sorted y itemgetter (de operator).
El ultimo valor se resta del primero dándonos la solución buscada.
Probamos on el fichero de test. la salida es verbosa pero permite comprobar todos los cálculos previos. Un TDD puro seria algo engorroso y yo (aunque no lo parezca) no tengo muchas ganas de teclear..
Atacamos el puzzle sin mas dilación...
Bueno pues algo engorroso (quizás por la forma de abordarlo a lo bruto) pero no excesivamente complicado.
El octavo de #AdventOfCode parte 2 en SQL. Un poco ñapas para mi gusto pero es lo que hay!
Empezamos como siempre..
Limpiamos linea alinea y separamos x, y, altura para cada arbol usando CTEs en secuencia.
Cruzamos cada arbol con su scan a derecha, izquierda, arriba y abajo con sub-consultas correlacionadas. Hay que cambair el orden de los que devuleven para que quedan en funcioón del punto de vista. Cada resultado se agrega en un array.
#AdventOfCode 5 Supply Stacks en SQL puro (PostgreSQL)
Si te gusta el SQL lo vas a flipar (creo) , sígueme en este triste historia (por lo de "La Roja") +
Empezamos como siempre, y toca cargar el fichero de test que ya tiene tela...
Empezamos enumerando las lineas del fichero (ya en la tabla de input), quedandonos con la parte de las pilas y calculando la longitud maxima de entre todas las líneas (por si caso no eran iguales)
Quien no sepa que esto que lea mis otros hilos porque ya va siendo lo mismo todo el rato
Tan facil que no lo voy a despiezar pues creo que se entiende de un vistazo y además esta comenetado. Convierte en rangos y comprueba inclusiones entre ellos.
Bueno, de vuelta al #AdventOfCode 3 Rucksack Reorganization
Empezamos leyendo los datos con ayuda de una tabla y restricciones adecuadas..
He creado una vista con la solución y así la reuso para pasar el test y luego el fichero de entrada del desafío.
Seguidamente os explico, aquí la muestro plegada junto con el código completo.
Empiezo mapeando las prioridades ['a'..'z'] -> [1..26] y ['A'..'Z'] -> [27..52] con dos consultas sencillas y el operador UNION ALL
Este año en la encuesta de evaluación docente me van a crujir los alumnos y seguramente las prácticas de la asignatura son lo más parecido a lo que demandan cuando recién aterrizados en el curro te quejas de lo que no visteis en la universidad
Les hemos hecho currar a base de bien primero un diseño con su modelo entidad relación y su diccionario de datos justificando cada dato cada dominio cada tipo y créeme que les hemos hechi pelear cada punto y cada coma lo mismo para el modelo relacional...
después nos hemos dado un conjunto de datos con muchos defectos han tenido que cargarlos en tablas y examinarlos y razonar sobre qué transformaciones o incluso qué modificaciones a su modelo original deberían hacer ( Y efectuarlas!)