Bienvenido al sector de Internet que no sabías que existía.

sábado, 11 de septiembre de 2021

Bichitos

Si esto aún no pasó... ¿pasará?

--- 

Ya no había sol en el cielo, ya no había sonidos afuera, ya habíamos cenado. Todo indicaba que era la hora de dormir.

Metido entre las sábanas y frazadas, intentaba en vano recordar la última vez que se habían cambiado.

Debían estar ahí desde el primer día que hizo frío. O empezó a refrescar.

Estando vecinos a la primavera, esto había sido hace un rato ya.

Pensaba... ¿3 meses? ¿4 meses? ¿Están desde el invierno anterior, 1 año? No se sabe. Pero andan.

La cama está empotrada en un lugar rebuscado, de difícil acceso cuando se habla de cambiar las sábanas. Podría tranquilamente suceder que tu espalda se convierta en una copia fiel de la del David, insultos mediante.

No es fácil cambiarlas. Y, más importante, no parece necesario. Sumándole la volatilidad del tiempo, los meses pueden transcurrir como si nada, y las sábanas permanecer ahí.


Además, convierte al dueño en un benefactor social. O 'sucial'.

Esta cama que me estaba dando cobijo, también lo hacía a unos bichitos de tamaño pequeño que alguna que otra vez había visto por ahí.

No sé de dónde vinieron, pero ahí andaban. Charlamos un par de veces, incluso llegamos a jugar unas manos de truco.

También nos divertimos jugando a las peleas juntos, cuando aparecían montados en mis brazos o piel en general.

Ese día, ya metido en la cama calentita, tapado con todas las capas hasta arriba, salía solo un chorrito de luz proveniente del celular entre la oscuridad espesa de la habitación, celular que había agarrado para conversar un poco por WhatsApp antes de zambullirme en el sueño.

Siento un poquito de comezón en la piel. Me causó gracia, porque yo le había dicho a los bichitos que no me molestaran para dormir.

Me rasco, y le comento esta curiosidad a mis contactos por el celular.

Es interesante, porque llegado un punto ya no sabemos qué es real, y qué es invento del cerebro.
Empiezan a picar más partes del cuerpo. Me sigo riendo, como si me estuvieran haciendo cosquillas mis amiguitos.

Pican un poco más. Levanto las sábanas y me fijo. No había nada.
"¡Qué curioso! Me lo estoy inventando todo. Ya me dejaron en paz, son respetuosos y como les dije que no me piquen no me pican."
A vos te debe estar picando el cuerpo ahora, y no hay ningún bichito por ahí. ¿No? El cerebro es curioso. ¿No?

Hasta que siendo una mordida.
¡Me parece muy divertido que el cerebro pueda crear sensaciones así, tan reales, tan intensas!

Me toco, en el muslo, y siento algo húmedo y que me duele, como una herida recién causada. Justo donde había sentido la mordida. ¡Increíble! No sabía que podía generar una sensación tan real solo con la mente.

Dejo el celular a un costado, y la oscuridad de la habitación se vuelve ahora total.


Más cosquillitas. Ahora en los pies. En ese extremo de la cama, las sábanas se están saliendo un poco y siento un poquito de frío.

Ya se habían caído todas las capas de ropa de cama al piso, unas 4 o 5 veces en todo el tiempo en el que estuvieron en servicio.
Ante la vagancia de buscar sábanas nuevas, opté por dejar esas mismas, total el piso no estaba tan sucio. El rocío de la noche lo limpiaba a diario.

Siento algo suave entre mis dedos del pie izquierdo. Exclamo un sonido medio risa, medio nervioso, porque ya me estoy empezando a molestar. Digo. Sean los bichitos o sea yo, ya quiero dormir.

Cierro los ojos, me ladeo hacia un costado, y decido ignorar todo esto para dedicarme a dormir de una vez.

En el oído nunca me entran bichos.
Por eso cuando sentí un cienpiés caminando e introduciéndose en el conducto auditivo, supe que no era real. Y cuando pasó el segundo, lo mismo. Los ignoré con seguridad.


"Mañana creo que debería cambiar las sábanas", pensé, porque ya me iba a quedar esta sensación de incomodidad, como un recuerdo rarito, y prefería dormir bien antes que eso.

Pero no llegué a terminar de pensarlo, porque ahí escuché por primera vez el ladrido y gruñido. "Ah, bueno, es 4D este espectáculo." Y lo era.

Mis dedos del pie, a juzgar por el sonido, eran parte de su cena ahora. "Ufa, están a full estas imaginaciones. Debo estar semi dormido semi soñando."

Dolía. Bastante. Y empecé a sentir también el fluido caliente colorado saliendo de ahí, posiblemente manchando el colchón o la sábana. "Bueno, si fuera real tendría un motivo para cambiarlas", pensé, y me reí.

Y ahí es cuando cae el árbol.

Al lado mío, se cae un pino de 30 metros de altura. Y no hace ruido.
Ni un decibel.

¿Cómo sé que cayó? Por los pájaros que volando me golpearon en la cara justo después de que las ramas me rasparan todo.
Pero ya estaba durmiendo, así que no era nada tan terrible.

Es una buena idea ignorar todo lo que pasa y concentrarse en nada, para relajarse y poder dormirse mejor.


Funcionó bien, porque después de eso me desperté en el hospital, con la pierna enyesada, el muslo morado, y miraba a mi alrededor un poco confundido mientras me explicaban que me habían extraído varios insectos del tracto auditivo, y que no debería tirarme en el medio del bosque durante la noche así nomás, que me iban a ayudar, etc.

No entendí bien por qué me decían eso, capaz me hablaban de una peli, o me dijeron "vos qué" y yo entendí "bosque", en fin.

No sé qué habrán hecho con las sábanas, espero que las hayan lavado porque si voy a dormir de nuevo ahí me va a picar un poquito la piel.

miércoles, 7 de abril de 2021

Programas autorreplicantes (guía)

 Esta es una guía para escribir un programa que, al ejecutarlo, imprime su propio código. (No hablo de que sale por una impresora en una hoja, imprime en pantalla...)

¿Es posible hacer esto? Sí. Por algo te hice esta guía. Empecemos.

Introducción

Este tipo de programas (llamados quine, o ouroboros en inglés) se puede hacer de muchas formas. Hay gente muy loca que inventa todo tipo de formatos para llevarlos a cabo, variando entre lenguajes, por supuesto.
En Python se puede ver un ejemplo muy, muy corto de un programa que se autorreplica al ejecutarse:

s='s=%r;print(s%%s)';print(s%s)

Ese programa de una sola línea es código perfectamente válido en Python, y al ejecutarlo imprime en pantalla exactamente los mismos caracteres que conforman su código fuente.
Puede ser un poco raro de entender, pero su funcionamiento es en realidad sencillo (valiéndose de algunas curiosidades sintácticas) y sigue los mismos principios que voy a comentar en la guía.

No voy a explicar ese programa, sin embargo.

Idea principal

Todo quine típicamente debería tener estos componentes, de alguna manera:
  • Su código
  • Una representación de su código como texto
  • Una instrucción que imprima esa representación
En el caso anterior en Python, la variable s es una cadena (string) que contiene el código fuente del programa, no de forma exacta, sino de una forma que al printear (con ciertas modificaciones) producirá el código fuente.
Veamos cómo replicar esto en un programa en C.

Pasos a seguir

Voy a dar una serie de pasos para recrear esto en el lenguaje C. Es relativamente sencillo y mecánico si consideramos algunas cosas.

  1. Escribir un programa que haga algo. Nos vamos a dar la libertad de hacer uno que no haga nada, excepto printearse a sí mismo, en esta ocasión.
  2. Crear una variable que contenga TODO el código fuente, reemplazando las nuevas líneas, tabulaciones, comillas dobles por %c, y a sí misma por %s. Manejaremos esto posteriormente.
  3. Agregar una línea de printf() inmediatamente antes del fin del programa. Esta será la encargada de printear el código fuente. Hay que agregarla en la cadena también.
  4. Acomodar los argumentos de printf() para que reemplace cada %c por el carácter necesario, y %s por la cadena que definimos.
    Escribiremos su representación en ASCII para cada %c, como número decimal, para mayor facilidad. Estos son carácteres que nos complican especialmente la vida en la generación de quines, ya que se representan como secuencias de escape en las cadenas (\n, \t, \" respectivamente. Mucho lío manejar esto, porque la barra \ también necesita ser "escapada" en la representación. Mejor ASCII):
    1. nueva línea = 10
    2. tabulación = 9
    3. comillas dobles = 34
  5. Escribir los argumentos del printf() en la cadena de texto, ejecutar el programa, y gozar.
Ahora vamos a ver un ejemplo práctico de esto.

Manos a la obra

Empecemos escribiendo una plantilla básica de un programa en C:

#include <stdio.h>
    int main() {
        return 0;
    }
Uno podría hacer que este programa haga algo, pero decidimos dejarlo así para esta guía. Si se ejecuta eso, solamente retorna 0 y termina su ejecución.

Vayamos al paso 2 y agreguemos una variable para contener la cadena. Dejémosla vacía por ahora.


        #include <stdio.h>
            int main() {
                char cadena[]="";
                return 0;
            }
    

Agreguemos la línea del printf() a continuación:


        #include <stdio.h>
            int main() {
                char cadena[]="";
                printf(/* para completar */);
                return 0;
            }
    

Y pasemos a ensuciarnos las manos. Vamos a completar la cadena con todo el código fuente. Vayamos de a poco.
Vamos a ver cómo debería lucir esa cadena solita:


        "#include <stdio.h>%cint main() {%c%cchar cadena[]=%c%s%c;%c%cprintf(/* para completar */);%c%creturn 0;%c}"
    

Pero, ¿quejesto?
No entrar en pánico.
Es el programa, puesto en una línea sola, y cambiando lo que dije que había que cambiar:
  • Saltos de línea por %c
  • Tabulaciones por %c
  • Comillas dobles por %c
  • La cadena en sí por %s
No te mentí. Yo te había avisado de esto. 👀

Entonces, pongamos eso en la variable que creamos.


            #include <stdio.h>
                int main() {
                    char cadena[]="#include <stdio.h&t;%cint main() {%c%cchar cadena[]=%c%s%c;%c%cprintf(/* para completar */);%c%creturn 0;%c}";
                    printf(/* para completar */);
                    return 0;
                }
        

Completemos el printf() ahora.
Es fácil: primero, va la cadena. Después, el valor de cada elemento a reemplazar en el formato de la cadena (son los %c y el %s).

Como vemos que el primer %c corresponde a un salto de línea, el primer número será un 10.
El segundo es otro salto de línea, otro 10.
El tercero es un tab, entonces ponemos 9. Etc.

Esa línea debería quedar así:


            printf(cadena,10,10,9,34,cadena,34,10,9,10,9,10);
        

Vemos que para el lugar de %s pusimos simplemente el nombre de la cadena, y para las comillas, 34.

Entonces lo ponemos en el código:

            #include <stdio.h>
                int main() {
                    char cadena[]="#include <stdio.h>%cint main() {%c%cchar cadena[]=%c%s%c;%c%cprintf(/* para completar */);%c%creturn 0;%c}";
                    printf(cadena,10,10,9,34,cadena,34,10,9,10,9,10);
                    return 0;
                }
        
Y no olvidemos de cambiar lo que dice /* para completar */ en la cadena también:

            #include <stdio.h>
                int main() {
                    char cadena[]="#include <stdio.h>%cint main() {%c%cchar cadena[]=%c%s%c;%c%cprintf(cadena,10,10,9,34,cadena,34,10,9,10,9,10);%c%creturn 0;%c}";
                    printf(cadena,10,10,9,34,cadena,34,10,9,10,9,10);
                    return 0;
                }
        

Y como dice el último paso, queda compilar, ejecutar el programa, y gozar. Porque ya terminamos.

Se puede compilar (usando quizás gcc programa.c), y ejecutar, para ver que efectivamente se imprime en pantalla exactamente el código del programa.

Incluso se puede ejecutar esta serie de comandos (en alguna plataforma basada en Unix) para verificar que funciona. Con un fuente hola.c:
gcc hola.c -o hola.out touch nuevo.c ./hola.out > nuevo.c gcc nuevo.c -o nuevo.out ./nuevo.out
Y debería printear nuevamente lo mismo.

Quiero más

Te dejo algunos links.

Chau

Nos vemos.