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

jueves, 18 de enero de 2024

Músculos dulces

El agua te golpea como una brisa de mermelada. Brazada, brazada, son como cucharadas. Recientemente había visto un video que mencionaba que nadar en una pileta llena de agua cuesta el mismo esfuerzo que nadar en una llena de jarabe. Aparentemente, la fuerza adicional que puedas hacer en la pileta con el fluido más viscoso se cancela con la fuerza de resistencia que aplica el mismo líquido. O sea, podés empujar más fuerte, pero avanzás menos. Yo aún no lo probé, así que no puedo confirmarlo.

¿O sí?

Brazada, brazada, sigo sintiéndome en un tazón de cereal con leche, azúcar. No es un pelado lo que estás viendo. No es agua lo que estás viendo.

Innegablemente, practicar natación es una de las cosas más disimuladamente asquerosas que realizan los deportistas y entusiastas con una frecuencia sorprendentemente alta.
Si te diera un vasito de jugo de axila, un vasito de un buche que me acabo de hacer, una botellita de una infusión extraída de la calva incipiente de un cereal, estoy seguro de que no dudarías un segundo en tomarlo o, al menos, enjuagarte los dientes con esa mezcla espectacular. Digo, en base a lo que se ve en el natatorio, ese es el accionar de todo nadador.

Y considero que estuve bastante ligero en la elección de bebidas.

Cómo olvidar el momento en el que aquel o aquella nadadora inmensa, de proporciones astronómicas y velocidad caracol, nos deleita gratuitamente con un espectáculo sin par desplazándose a la velocidad del agua de pantano frente a nosotros. Un espectáculo para todos los sentidos, evocando todas las emociones, todos los placeres. Siempre es bueno probar nuevas bebidas.

Y seguir nadando en el dulce de leche. En la crema pastelera. En la crema chantilly. El mousse. El almíbar.

Un nadador principiante puede nadar 1000 metros en menos de una hora. Uno intermedio, unos 2000. Aquellos avanzados, que ya comienzan a hablar más fuerte y a acaparar andariveles como si se tratara de cosa propia, pueden llegar a los 3000 o incluso más. Los que saben pueden llegar a los 5000.

¿Alguna vez caminaste varios kilómetros por un bosque de churros? ¿O por uno de medialunas? ¿Podías hacerlo ahora? Por favor. Te espero.

Considerando que volviste de caminar por lo más parecido a una reserva natural de brownies que encontraste en tu barrio, en primer lugar te felicito; en segundo lugar, te quiero hacer notar lo siguiente:

¿Cómo sentís los músculos?

No es fácil atravesar un mato así de espeso y salir airoso. Lo más probable es que salgas azucaroso.

Van 1000 metros, 1500 metros, 2000 metros. Brazada, brazada, patadita, y azúcar. Patada, brazada, patada, y azúcar. Listo. Una hora. Terminé.

Salís del agua, directo a la ducha. Hay que sacarse el jarabe de la piel; podría resecarla. Después te pica todo y no está bueno. Duchita, y elongamos.

Estiramos una pierna. Cómo duele, che. El brazo, siento los músculos cortitos. Son como tiras de caucho que están un poco estiradas, pero no van más, están duros, cortitos, dulces.
La leche abunda, y se siente. Estirando cuádriceps, estirando bíceps, tríceps, me siento el hombre más rígido del planeta. Sé que mañana voy a tener los músculos totalmente dulces.

Cuando te despiertes, serás el hombre galleta. Toda la sensación en tu cuerpo entero será de dulzura. No es cansancio. No es fatiga. Están dulces.

Abrite un brazo, fijate, vas a ver cómo están.

Probalos, atrevete. Es el sabor más dulce que hayas sentido.
Se ven blancos. Qué raro, ¿no? No sé qué es esto. Pero es dulce.

Intuyo que la próxima vez me voy a disolver en la pileta.

lunes, 6 de noviembre de 2023

sábado, 2 de abril de 2022

use crate::Historia::*;

Nota del autor: este género no existe. Hay muchas cosas que usted creerá que entiende pero realmente no será el caso. Asimismo, habrá muchas otras que no creerá que entendió, pero sí las habrá entendido.

Aconsejo el uso de dreamlink.cloud y del cerebro abierto. De ahora en adelante, ulterior a los guiones y con el permiso de su actual dueña, leerá un regalo.


------------


Ciudad de Buenos Aires, en algún momento de la historia...

[Sonido estridente de tren subterráneo] ...

...

...

[Tren se detiene] ...

[Ruido de puertas neumáticas abriéndose] ...

...

[Chicharra aturdidora] ...

"¡Eh! ¡Eh! ¡Acá bajamos!" => corren

[Puerta cerrándose sobre una persona] ...

"¡Ay!" => se interrumpe el cerrado de la puerta debido a cuerpo extraño bloqueante

[Ruido de puerta neumática abriéndose] ...

[Chicharra aturdidora] ...

"Ni me di cuenta que ya estábamos acá" :: "No, me re dormí yo"

[Puerta se cierra] ...

[Tren se retira emitiendo sonidos galácticos] ...

...

...

"Me encanta el ruido que hace este tren che. Bueno, llegamos. Mi lugar en el mundo."

"¿Conociste todo el mundo vos? Mirá, no la tenía esa."

"Qué mala sos..."

"Jsjsjs"

...

...

const v = vic![[[
   17:16 || <Despertando>
   17:16 || <Última vez conectado: 2:03>
   17:17 || <Error fatal recuperando entradas de diccionario>
]]]

...

"Bueno. Acá estamos. ¿Dónde queda? Sinceramente, no me acuerdo. Nunca sabré si no me acuerdo porque me olvidé, o si no me acuerdo porque me hacen olvidarlo."

"Mjm. Y entonces para dónde vamos."

"Y. Tenés que hacer que ello te busque a vos."

...

const r = <?tuxon
   wpm: 35
   pinta: std.ALTA
   distorsión vocal: std.voz.ALTA
   4k-enabled: true
?>

...

"Mirá, creo que es por ahí. Fijate esa calle como empieza a curvarse."

"Hm." => estímulo

"Y a partir de acá... Estamos ingresando al laberinto."

import { Ciudad } from 'CABA';

Ciudad.barrios.Chas.begin()

[Maquinaria antigua moviendo engranes subterráneos] ... => $p = patrón de calles [1..=100].pickOne()

"La última vez que vine no recordaba esta parte... Nunca puedo encontrar la misma esquina dos veces."

"...¿Se estaba moviendo esa esquina o me pareció?"

"Y, no me extrañaría, jajaja" => match { Chiste } => FAILED

Ciudad.barrios.Chas.setPatrón($p)

"JAJAJAJA, MIRÁ ESTO, HAY UNA CALLE QUE SE LLAMA JAMÓN CRUDO" => éxtasis

"JAJAJJSJSJAJAJ increíble"

[Sonido de cámara] ...

=================================================================
.....El barrio tiene sus orígenes en épocas y condiciones inciertas. Hasta el día de la fecha, no se sabe si es obra de un ingeniero, un arquitecto, un grupo de personas, o seres alienígenas. No hay registro de su fundación. No hay evidencia de parcelas anteriores en esa zona. No hay documento original de sus cloacas o trazado; tan solo copias hechas por la comunidad, basadas en exploraciones individuales. Abundan, eso sí, leyendas urbanas.....
=================================================================

v.cumplirAños() => FAILED with ErrCode: year is 2022

Ciudad.barrios.Chas.teleportToVenus(Ciudad.barrios.Chas.getPeople()).withTimeTravel("past",{"years", 157})

"A partir de acá, ¿no parece otro lugar? Digo, es absolutamente distinto a la avenida por la que veníamos hace 2 cuadras."

"Sí. La verdad que parece como salido de un cuento." => 樂

[Caminan y ríen] ...

...

...

"Okey. Estamos en el cruce de Berlín y Gándara. Prestale atención a la plaza. Hay una plaza en esta esquina, ¿no? Berlín y Gándara tiene una plaza. ¿Estoy loco?" => sí

"Jsjsj, sí, hay una plaza" => ta loco

"Dale. En cinco minutos te vuelvo a preguntar."

[Caminan derecho y piensan] ...

...

Ciudad.barrios.Chas.removeSquareFrom("berlin","gandara")

"OJO, OJO, MIRÁ CUÁL ES ESA CALLE"

"No llego a leer ni en pedo. ¿Dice Gándara? ...¿Qué?" => sonrisa

"Pregunta: Berlín y Gándara, ¿tiene una plaza en la esquina?" => éxtasis

[Felicean por unos minutos] ...

Plaza::missing => true

"La verdad que me gusta este lugar, eh"

"Sí, qué se yo, tiene esa mística, esa cosa intangible totalmente misteriosa, a mí me encanta mucho."

"Mirá esto, ese árbol tiene hojas... De papel. Acá se cayó una"

"¿Qué es eso que dice? ¿bafybeievzasuxoadvxgsymah2pfgdtuq6ydyoai6d4bhrotom64l6rbgp4? No tengo ni idea"

"Yo sí sé qué es. Después lo voy a ver."

"Como decís vos: Jorge Misterio eh"

"Jsjsjs. Significa que alguien dejó una huella."

[Se guarda la hoja en el bolsillo] ...

r.charlar() => FAILED with ErrCode: Object of type <?tuxon ...args...?> missing method "charlar". Did you mean "uint"?

"Que camioneta más rara esa."

"Sí, es como estar en otra época, ¿no?"

"Sí, muy. Tiene esa cosa lúgubre, como inquietante... Me provoca una sensación rara. Siento como si se hubiera estancado el tiempo acá. Como si, por alguna razón, el flujo del tiempo hubiera decidido esquivar esta zona."

"¿Tipo flujo como campo vectorial?"

"Ponele. Tamos flasheando una banda me parece"

Ciudad.barrios.Chas.elems().filter(e => e.type=="van"&&e.abandoned).relocate()

"Y sí, pero no queda otra creo. Era la idea, ¿no?"

"Che, ¿esa camioneta no es la que vimos la cuadra anterior?"

"Lmao. Tenés razón, era igual. Bah, salvo que haya otra igual y abandonada el mismo día, ni idea"

"Alto miedo"

[El sol sigue bajando] ...

"Hola, chee, sscuchame... Me, mee, me filmás un video?"

"Mmm dale" => lmao es gaspi me hago el boludo

"JAJAJA" => es gaspi diooos

"Ya está filmandoeee"

"Sisi, vos mandale" => JAJAJ es gaspi a ver que hace

"Bbbbbbbaaaaaauuuness, soy Víctor Ludeña, sssí, Lu-deña, y hoy que estoy acá en la esquina de Bauness y Boliviaaano, te quiero invitar a que vengass a mi seminario. Yo soy un actor-"

[Estalla en risa] ...

"Disculpame chabón, pero no puedo, ajajaja, me quise hacer el boludo pero no aguanté la risa. Te amo Gaspi"

"Uuu bueno cheee lo dejamoss igual en el video boluddeeeoa"

"JAJAJA"

[Finaliza el sketch] ...

[Caminan unas cuadras] ...

"JAJAJAJAJA CÓMO NOS VAMOS A CRUZAR A ESTE CHABÓN ACÁ"

"JAJASJDSJDJS SÍ NO SÉ FUE INCREÍBLE"

"ENCIMA EN VEZ DE BUENASS DIJO BAUNESS"

"JSJSJSJJSJAAJSJ"

Ciudad.barrios.Chas.swap("bauness","cadiz")

"Siempre que vengo acá hay una esquina que tipo, dobla la calle pero no cambia el nombre."

"¿Cómo?"

"Sí, tipo, vos venís por la calle Dublín y doblás en la esquina en la calle Dublín. Es re raro, pero siempre que vengo me da la impresión de que la calle que hace eso es diferente."

...

"¿Qué pasó?"

"Nada, 4428. 4 y 4, son 2 cuatros, y suman 8. Me gustó el número"

"Ah, mirá" => qué bonito lo que notó

"Bancá que anoto una cosa en el celu"

"¿Ese graffiti que dice esa cosa rara? ¿Otra huella?"

"Sí, otra huella"

------------------------------------------------------------

me perdí en charque pas

bafybeiavz3fhy5joefyqfqwrgcbixva47bwc2wgyoavfxv2brxl55r4zki

------------------------------------------------------------

"Che... Sabés que un poco me suena esta zona... Creo que estamos cerca de la esquina esa que te decía que tiene el mismo nombre..."

"Mirá, acá, acá!" => estímulo

"Síííííííííííííííí, Bauness y Bauness!!" => satisfacción

"Literalmente los autos que vienen por Cádiz pasan a Bauness sin doblar, y los que vienen por Bauness doblan y pasan a... Bauness. Esshh increíííble"

"Siempre me pregunté cómo será vivir ahí, cómo le indicás a la gente para que llegue bien..."

[Se sientan en la esquina de Bauness y Self] ...

...

Ciudad.barrios.Chas.addNPC(corner:{"bauness","bauness"})

<<< Chicos,,,,,, no les sugiero que estén sentados ahí,,,,, doblan los autos,,,, vayan al cantero este ,,,,,,>>>

"¿Y este?"

"Wtf"

"Eeeh, bueno, gracias!" => exclamando

let npc = Ciudad.barrios.Chas.getNPC(corner:{"bauness","bauness"})

npc.intoHouse(corner:{"bauness","cadiz"})

"Jajaja, nono, jodeme que vive ahí en esa esquina" => XD

"Lmao. ¡Eh! ¡Señor! ¿Cómo es vivir en Bauness y Bauness?" => yoloing

npc.handleInput()

<<<Bueno,,,,,,,, no es fácil,,,,, porque es difícil,,,,, usted sabe,,,,,,, la gente no se puede orientar bien en el barrio ,,,,,,,,,,,,, pero es divertido porque la pizza me llega siempre fría,,,,,,,,,,,,,,,,,,,,,,,,,>>>

...

...

npc.laugh()

<<<Ja ja ja ja ja ja>>>

[ambos] "Jajajaja" => q tipo más raro no

npc.terminate()

<<<Chau>>> => poof

"Wtf el chabón acaba de desaparecer o estoy alucinando?"

"WTF"

"..."

"..."

"Es medio tarde ya. Creo que estamos cansados. Vayamos volviendo..." => panic!()

"Dale... Me parece bien" => todo!()

...

...

try {

   v.reply()

} catch (error) {

   // TODO: bad code! handle the error instead of ignoring it!

   if (error.msg == "Failed to load dictionary entries") return;

}

"Uh, a ver, mandaron un mensaje en respuesta a lo que habíamos preguntado hoy a la mañana."

"Jsjsjsjsjs, puso nada más 'No creo'. Tipo, más conciso imposible."

"Jsjajaajajj literal. Me encanta."

[Caminan 3 minutos y 16 segundos] ...

...

"Che, a todo esto, ¿vos sabés cómo salir de acá?"

"No, la verdad te estoy siguiendo a vos"

"Ah, buenísimo. Yo estoy haciendo lo mismo con vos"

"Bárbaro. Bueno, vayamos derecho que en algún momento salimos seguro"

"Yyyy... Yo no estaría tan seguro la verdad. Ya viste que hay calles circulares, cosas así medias raras"

"Bueno, si vemos las mismas casas varias veces doblamos y agarramos por ahí"

"Okey dale. Y si no siempre tenemos Maps para mirar"

[Caminan 6 minutos y 25 segundos] ...

...

Ciudad.barrios.Chas.setRandomPattern()

[Engranes subterráneos alteran el patrón de las calles] trux, trix, trux, trix

...

"No sé si te pasó a vos, pero yo ya no registro los lugares por los que pasamos... Tipo, como que alguna casa me parece familiar pero, mi sentido de la orientación me dice que debería estar como en la dirección opuesta..."

"Bancá. ¿Esa no es la de Bauness y Bauness? ¿Donde desapareció el chabón?"

"...Sí, tipo, es igual."

"Pero estamos en Gamarra y Del Temple"

"Eu. Eso sí me suena, es como, re afuera de la parte laberíntica. Wtf"

"Uh, che, estamos ultra perdidos. Bancá que agarro el celu así nos orientamos"

"Dale"

500 Internal Server Error

"No me estaría cargando... A ver, probá vos"

"Seh, estaba probando, no me agarra Maps..."

"Y eso que señal tengo. Tipo, me anda todo bárbaro"

"Weird. Bueno, caminemos hasta que agarre, supongo"

[Caminan 12 minutos y 58 segundos] ...

...

...

Ciudad.barrios.Chas.setRandomPattern()

[Engranes subterráneos se mueven] ...

[Se atoran] ...

ERROR: Method setRandomPattern() failed with ErrCode "Unable to move street"

ERROR: "Chas" of type Barrio exited with code 6 = "Catastrophic failure"

INFO: Starting recovery...

<Shutting Down>

...

"No me dan más las piernas, la verdad. Sentémonos un toque"

...

<Booting>

@ Downloading dependencies... 5%

...

"Dale, te acompaño. Fue un día larguísimo hoy. Pero la pasamos bien"

"Síí, eso seguro"

...

@ Installing NPCs and Ghosts... 28%

...

"¿No notaste que de golpe todo está como... DEMASIADO tranquilo? Tipo. No hay absolutamente nadie en la calle. No pasó absolutamente ningún auto en los últimos varios minutos. No se escuchó ningún sonido de ninguna casa. Ni se mueven los árboles ni hay cosas en las calles. Es más, mirá, no hay ni autos estacionados..."

[Voltean hacia atrás] ...

"No hay... Qué............ Directamente no hay ningún auto"

@ Starting system...

@ Placing items

... Cars... 56%

... People... 12%

...

"Okey, no, algo acá no anda bien. Están literalmente apareciendo autos y personas" =>

"RAJEMOS BOLUDO CORRAMOS" => actual panic!()

[Corren por su vida] ...

...

@ Testing street pattern 56 out of 1427...

[Siguen corriendo, pero las calles siguen cambiando] ...

...

...

@ Rendering everything... 88%

[Aparecen autos y camionetas abandonadas] ...

[Aparecen personas sin renderizar] ...

@ Testing audio files...

[Suena música de las casas] ...

[Suena más música, suena en todas las casas al unísono] ...

[Suena MUY fuerte] ...

[Suena REALMENTE MUY fuerte] ...

[Se desmayan. Caen al suelo rendidos] ...

...

...

@ System boot completed.

>

------------------------------------------------------------

"¿Che, vamos a Parque Chas?"

"¡Dale!"

[Caminan] ...

"Mirá... Un árbol con hojas... ¡De papel!"

"Uh, a ver"

"¿Qué es esto? Tiene como unos garabatos que no dicen nada"

"Sí, ni idea."

[La arrojan al suelo] ...


[Papel arrugado] ...

@{ <bafybeid7c3o77trgeglf3qw2sswf25frwqel45w47wjcxotjbbwodwugii> }@


r.chau() => "Tervit"


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.