The Code Maverick (3/3 💉) Profile picture
#Codenares (Lite) #EUROBOTUAH Nullum magnum ingenium sine mixture dementia fuit

Dec 6, 2022, 26 tweets

Le saqué algo en claro al partido de España...

#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)

Los contenidos de las pilas están en vertical, malo, malo para las tablas de un SGBD. Hagamos una explosión para poder reagrupar mas adelante. Cada símbolo es la letrita dentro de cada par de corchetes

Hay que renumerarlso de entre cada linea y cada stack (para no perder la posición relativa)

Finalmente usamos rank para saber la posicion relativa a partir de cada posicion absulta y cada linea.
Y la tabla de stacks consiste en recolectar los resultados de estas CTEs.

Ahora quiero ver los comandos como simples comandos pop -> push entre pilas, pero debo extraer el número de items a mover y la pilas.

Primero extraemos la parte de los comandos de la tabla de input y depuues repetimos pasos y además partimos las descripciones en un array.

Las palabras 2,4,6 del array son la cantidad de ítems y origen y destino (pilas). En base a eso explosiono los comandos en un montón de "single commands" (de 1 solo ítem de una pila a otra).

Para aplicar un comando debo saber en un momento dado las cimas de cada pila y para eso me costruyo una vista, calculando las cimas de la pila origen y destino para cada comando potencial.

Es una vista, es "lazy" no calculo nada que no se vaya a pedir en realidad..

Cuando haya acabado de aplicar cualquier comando hipotético quiero saber el elemento en la cima de cada pila ¿Como? Pues con otra vista!

Como ejecuto un comando, pues con un UPDATE para lo cual me voy a hacer una función para encapsular este proceso. ¿Ya era hora no? Bueno, es por ejercitar un poco de todo...

Ahora como ejecuto las funciones, pues para cada comando genero una sentencia que llama a la función...
¡¡Pero esa consulta sólo devuelte un string que parece SQL!! diréis con razón, y es verdad en SQL pero no hace nada , solo sale por pantalla...

Ahora haremos magia, un poco de magia de PSQL con el metacomando \gexec, no seais vagos y RTFM. Si me hubieran dado a mi un mnnual tan cojonudo cuando yo estudiaba!!

Aqui os lo enseño todo junto, la consulta genera SQL que sale por pantalla y queda en el buffer de salida de PSQL.

\gexec copia el buffer de salida en el buffer de entrada y ejecuta uno auno esos comandos.

Como la función devuelve texto vereis una explicacion de cada movimiento

Creedme que se tarda mas en imprimir todo lo que hace que en hacerlo... En mi caso salío poco en el test pero el fichos completo fué un chorreo de 1 minuto y caso instantaneo cambiando el tipo de la función de TEXT a VOID.

Y todo el pésimo futbol de "la roja" quedó transformado en una estrellita.

Y aquí paro ya porque estoy derrengaoooo si miro Hoy la segunda parte me voy a acordar de la madre del creador de #AdventOfCode

No me gustó como hice este ejercicio así que lo he refactorizado un poco.

Construiremos secuencias de 2 y 3 letras distintas. A partir de ahí haremos las de 4 letras y luego las de 7 letras y por último las de 14 letras.

Empezamos...

Paso de limpieza y enumeración de letras.

Secuencias de 2 letras consecutivas distintas, hcaemos auto reunion de la tabla de 1 letra y nos quedamos con índices consecutivos con letras distintas. Finalmente concatenamos las letras en un array.

Secuencias de 3 letras consecutivas distintas. Básicamente como la de 2 letras pero con 3 letras y tambiín generamos un array.

2 secuencias consecutivas de 2 letras hacen una de 4. Así que buscamos dos índices a 2 letras de distancia en las tablas de 2 y que los arrays no esteén solapados (elementos en común).

Con una de 4 y una de 3 consecutivas hacemos una de 7. La dinámica es la misma pero con tablas tipo "4letras" y "3letras" con fragmentos consecutivos y arrays sin solapamiento.

Con 2 de 7 hacemos una de 14. Básicamente repetir el procedimiento con 2 tablas tipo "7letras".

El fichero de entrada tarda un pelín mas pero es inapreciable para estos tamaños de ejercicio y hay que contar que el motor de #PostgreSQL hace sus optimizaciones...

Si hay explosiones combinatorias en el #AdventOfCode de este año aún no las hemos visto.

Share this Scrolly Tale with your friends.

A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.

Keep scrolling