domingo, 2 de junio de 2019

Tutorial de Cualquiera++

En esta pequeña guía mencionaremos algunos aspectos de Cualquiera++ que todo principiante debe tener en cuenta a la hora de comenzar a programar en este bello lenguaje. Comencemos:

Vamos a suponer que el lector ya cuenta con los conocimientos básicos de la programación, y se maneja con un nivel intermedio de confianza en otros lenguajes como C++, o C, o el que sea. Este artículo utilizará C++ como referencia a la hora de mencionar las diferencias que Cualquiera++ tiene respecto a C++, debido a que como podemos ver por el nombre, Cualquiera++ se ha basado en C++; de hecho, es una versión completamente mejorada y optimizada. Pero no me adelanto más, ¡empecemos de una vez!

Comportamiento del condicional 'if not' en Cualquiera++
A diferencia de otros lenguajes, Cualquiera++ no cuenta con el clásico operador 'if'. Para evaluar una condición, sólo es posible analizar si la condición no se cumple. Los creadores han optado por hacerlo de esta forma dado que acelera los tiempos de procesamiento y hace que el código sea más difícil de leer, y por lo tanto más difícil de vulnerar (Cualquiera++ es un lenguaje diseñado específicamente para que los hackers no puedan molestar).
Veamos algunos ejemplos:

if not(a > b){{
      // hace algo
}}

En este caso, solo se realiza el contenido dentro del condicional si 'a' no es mayor a 'b', es decir, si 'a' es menor a 'b'.
Como podemos notar, la sintaxis es un poco diferente: se utilizan 2 llaves para abrir un condicional, y para abrir cualquier tipo de bucle o lo que fuera.

Tipos de variables en Cualquiera++
En este lenguaje podemos definir todos los tipos tradicionales admitidos en la mayoría de los lenguajes; es decir, int, float, double, char, etcétera. Como método de prevención, sin embargo, el compilador intentará convertir la variable a todos los otros tipos de dato, por si el programador se ha equivocado a la hora de hacer el código. Por supuesto, ese caso nunca sucede, así que el programa siempre dará error.
Para evitarlo, debemos incluir el comando "please do not convert". Son cuatro comandos por separado, veremos el comando 'please' en detalle más adelante (Cualquiera++ le da mucha importancia a los buenos modales). Entonces, la declaración de una variable podría ser de la siguiente manera:

please do not convert int nota;;;
please do not convert string nombre = 'Guido';;;

Podemos ver que es posible inicializar las variables en el momento de su declaración, como en el caso del string, y además vemos otra diferencia en la sintaxis: todos los finales de instrucción terminan con tres puntos y coma. Para asegurarse que el programador no se los olvide. De lo contrario, se dispara un comando 'shutdown' que apagará el ordenador en menos de 5 segundos. ¡Mucho cuidado! Recordemos que Cualquiera++ busca luchar contra el hackeo ilegítimo.

Bucles 'for' y 'while'
Estos dos bucles funcionan casi de la misma manera que en otros lenguajes, a diferencia de que, como no existe el condicional 'if', todos los controles se realizan de forma implícita con un 'if not'. Por lo tanto, se debe indicar que el bucle solamente se romperá cuando (en el caso del for) se agote el iterador, o (en el caso del while), cuando la condición sea falsa. Veamos un ejemplo para clarificarlo:

for (please do not convert i=0; i<5; i.increaseBy(1)){{
      please do not break;;;
      // hace algo cinco veces
}}

Cosas que podemos notar de ese pedazo de código:
No existe la forma de incrementar una variable como i++, o como i+=1, o como i = i+1. Para ello existe el método increaseBy(num) que le suma 'num' a la variable. Puede utilizarse para operaciones aritméticas, o para sumar 1 en estos casos. Nuevamente, una prueba de que la ilegibilidad de Cualquiera++ es su mayor fortaleza.
Notamos también el uso de la palabra 'please' para indicar que el loop no debe romperse siempre. Es decir, la condición "i<5" se controla internamente con un "if not", por lo que podemos optar por escribir la condición negada, o bien agregar el comando 'please do not break' (internamente lo que hace es negar el resultado del 'if not' para que equivalga a un 'if' tradicional).

NOTA: dentro del "for" se utiliza solo un ";" y no tres.

Veamos el ejemplo de un while:

please do not convert int contador = 0;;;
while(contador < 5 or maybe contador == 5){{
      please do not break;;;
      // hace algo si se cumple la condición
      contador.increaseBy(1);;;
      reminder{{
            please break;;;
      }}
}}

Vemos varias estructuras nuevas en este código. Vamos a explicarlas:
No existe el operador "<=", es decir "menor o igual", por lo que se debe incluir el "igual" como condición separada.
Los operadores lógicos son "and also", "or maybe", "exclusive or maybe", "not really", a diferencia de otros lenguajes. Su uso es análogo a "and", "or", "exclusive or" (pocos lenguajes tienen este notable operador), "not".
El bucle "reminder" se emplea para recordarle al compilador que debe romper el 'while' cuando no se cumpla la condición. Esto se debe agregar cuando el bucle tiene una longitud mayor a 5 líneas, o cuando no estamos seguro si lo recordará. Pues, el compilador solamente recuerda las últimas 3 instrucciones dadas, como forma de optimizar la memoria RAM utilizada.
Solamente debemos incluir un "please break;;;" dentro del mismo en el caso de un while. Podemos ver el bloque 'reminder' utilizado también en otros bucles como el 'switch', o en definición de algunas funciones. Pero eso lo veremos más adelante.

El operador 'please'
A diferencia de otros lenguajes, Cualquiera++ busca tratar de una forma más amigable al programador, y espera lo mismo de quien escriba el código. Por lo tanto, todas las instrucciones descritas a continuación deben incluir el comando 'please' en el comienzo:

  • please break
  • please do not convert
  • please do not break
  • please run
  • please do not shutdown(this)
  • please compile
  • please keep going
Hay algunos más, pero no los incluiremos todos en este artículo para evitar posibles fallas de seguridad. Recalcamos, la esencia de Cualquiera++ es su perfecta seguridad. ¡No podríamos dar todos los comandos así sin más!
Algunos de los comandos que no hemos explicado:
-"please run" se debe incluir al comienzo de cualquier código escrito en Cualquiera++, de lo contario el programa nunca se iniciará.
-"please do not shutdown(this)" es un comando que debe incluirse si uno no desea que ante el menor fallo de optimización su ordenador se apague (Cualquiera++ a menudo interpreta cosas erróneamente como fallas de la seguridad). shutdown(this) es una función de la librería 'safety', que se debe importar al comienzo del programa si se desea incluir el 'please do not shutdown(this)'.

NOTA: Las librerías se importan de la siguiente manera, al comienzo del código:

   please #include <nombreDeLibreria> thank{{sys.compiler;;;please do not answer;;;}}
Luego veremos el bloque "thank" en detalle.

NOTA 2: algunos novatos creen que si no se importa la librería 'safety' entonces no se podrá llamar al método shutdown() que apaga el ordenador, pero eso no es cierto. Cualquiera++ puede hacerlo porque tiene otro método idéntico propio. Esta llamada, sin embargo, se anula al utilizar el 'please do not shutdown(this)'

-"please compile" es un comando opcional, que no realiza nada a nivel software, pero genera la ilusión de que el programador está proporcionando motivación y ánimos al compilador, y le genera felicidad.
-"please keep going" es una forma alternativa de escribir 'please do not break'. Su función es exactamente la misma, pero a veces el programador querría optar por cambiar un poco las palabras para no aburrir al compilador.

Los otros comandos que contengan 'please' serán notificados al programador a medida que se tope con el error "#ERRORNAME: BePolite (line X)". Eso significa que en la línea número X falta un comando 'please'.

Definición de funciones
En Cualquiera++, la definición de funciones se escribe de la siguiente manera: (ejemplo con función que suma dos enteros)

please do not convert the following
please let me define functionName(param1, param2){{
      param1 istype int;;;
      please do not convert param1;;;
      param2 istype int;;;
      please do not convert param2;;;
      please do not convert suma = param1.increaseBy(param2);;;

      please return suma;;;
      thank{{
            functionName;;;
            please do not answer;;;
      }}
}}

Cosas nuevas en este código:
  • 'please let me define' es el comando que se utiliza para definir funciones. Así como en Python es "def", y en Javascript es "function".
  • 'please do not convert' debe ser incluido antes de la definición de la función, pues como Cualquiera++ no admite funciones con tipo de dato (como en C++ uno podría decir "void algo(x,y)", debemos aclararle que no la convierta.
  • 'the following' significa que el tipo de dato al que nos referimos está en la siguiente línea. Esto es análogo a escribir 'please do not convert please let me define functionName' en una sola línea, pero a veces el compilador libera la RAM antes y se olvida lo que está haciendo. Es una buena práctica utilizar 'the following' al definir funciones. No lleva ";;;" al final.
  • 'istype' se utiliza para indicar el tipo de dato que es un parámetro de la función. Esto es obligatorio. Por supuesto, a continuación se le debe indicar que no lo convierta.
  • NOTA: no podemos indicar 'istype' para todas las variables y luego indicar que no lo convierta, porque correríamos el riesgo de que el compilador libere RAM y olvide la instrucción.
  • El bloque 'thank', se utiliza para agradecer a la función por haber hecho su trabajo. El bloque 'thank' solo toma como contenido el nombre de la función, y como por default retorna "#ERRORNAME: YouAreWelcome" debemos aclararle que no responda con el statement 'please do not answer'. Pues, el compilador intenta ser educado, pero al solo poder hacerlo mediante un error, el ordenador lo interpreta como una falla de seguridad y se apaga.
NOTA: No utilizamos el bloque "reminder" porque en este caso toda operación está dentro de un margen de 3 líneas. Si tuviésemos la declaración de param1 a 6 líneas de distancia de la declaración de 'suma' como param1.increaseBy(param2), deberíamos incluir un 'reminder{{please keep going;;;}}' en el medio.
Operaciones matemáticas básicas (resta, división, multiplicación)
La suma ya hemos visto que puede ser realizada mediante el comando increaseBy(num). Veamos cómo realizar multiplicaciones:
Dado que no existe ninguna forma de multiplicar dos números, debemos hacer un bucle 'for' que sume X cantidad de veces. Por ejemplo, para hacer 2 * 3:

please do not convert int num1 = 3;;;
please do not convert int num2 = 2;;;
please do not convert int suma = 0;;;
please do not read emoji;;;
for(please do not convert int i=0; i<num1; i.increaseBy(1)){{
      please do not break;;;
      suma.increaseBy(num2);;;
}}

Luego, a "suma" se le sumará "2" unas "3" veces.
Lo único nuevo acá es "please do not read emoji". Esto se debe incluir porque, en este caso, al reemplazar num1 con '3' en la condición del for tendremos "i<3", y el compilador puede interpretar <3 como un corazón y causar un error que apagará la computadora.

Para darle amor al compilador, el programador debe optar por agregar comandos 'please' vacíos.
NOTA: incluir un 'please do not answer', porque Cualquiera++ automáticamente responde con un "#ERRORNAME: YouAreWelcome" y apaga el ordenador.
Ejemplo:

      please;;;
      please;;;
      please do not answer;;;
      please do not answer;;;

Por otro lado, si deseamos multiplicar números que son ambos no enteros (1,5 * 2,3, por ejemplo), o son ambos negativos, deberemos crear un script en otro lenguaje e importarlo como librería, dado que Cualquiera++ no lo admite. Cualquiera++ puede importar librerías en C, C++, o C#.

Sin embargo, si tuviéramos sólo uno de ellos negativo o con parte fraccionaria, no habría problema dado que increaseBy() puede trabajar con cualquier tipo de dato (incluso no números).
Eso sí, debemos aclarar que no convierta el número, y que es un float (o double, o long float, etc.) Por ejemplo, si sumaramos a+1,5:

      a.increaseBy(please do not convert 1,5 float);;;

Y si el número fuera negativo, debemos aclararle que es 0 menos que el número, e incluir el comando 'isnegative' al final, para evitar que se malinterprete como un error (y ya sabemos qué pasa cuando Cualquiera++ halla un error... SHUTDOWN), de la siguiente manera (para hacer a-5):

      a.increaseBy(please do not convert 0-5 isnegative);;;

Esto se debe a que la función increaseBy(x) internamente comienza con la instrucción "x istype auto;;;", sin un 'please do not convert', dado que asume que será un 'int' (y lo convertirá exitosamente, si es un 'int'). Pero 1,5 no es int (es un 'float' o 'double'), y -5 tampoco (es un 'isnegative int', o 'isnegative').

PROTIP:
Para dividir, podemos hacer dos bucles 'for' anidados, que controlen todas las multiplicaciones posibles y guarde el valor cuando se cumpla la condición de que su multiplicación sea igual al primer número. No haremos el programa porque la forma más corta de hacerlo lleva alrededor de 50 líneas.
Sugerimos utilizar otro lenguaje para realizar operaciones aritméticas.

Esto es todo por hoy.
Esto ha sido una breve introducción a Cualquiera++. Recomendamos que experimenten con este maravilloso lenguaje, y encuentren los errores por su cuenta, dado que esa es la mejor manera de aprender. Posiblemente deban encender su computadora varias veces, ya que cualquier error se interpreta como violación de la seguridad. Incluso hay algunos errores que eliminan el sistema operativo completo, o archivos muy importantes.
No diremos cuales, dado que allí radica la gracia y la diversión de aprender Cualquiera++ :)

¡Diviértanse!

Cualquier duda, dejar un comentario; gustosos la responderemos.

Un guiño del escritor:
please thank{{please do not convert reader isObject;;;please do not answer;;;}}

(veremos clases y objetos en otro artículo)

viernes, 10 de mayo de 2019

Cómo ser un calendario humano (remake)

Un remake de una vieja entrada... Disponible aquí. A ver si lo logro explicar mejor.

A menudo para entretener a la gente le pido su fecha de nacimiento... "26 de septiembre de 1999". Y luego les digo "¿te acordás si ese domingo llovió o había sol?". La mayoría se ríe, alguno que otro se queda un poco perplejo, existen también los que responden "ah no pero vos estás completamente demente". Hay de todo, como en todos los aspectos de la vida, mucha variedad.
Pero también están los que preguntan, con sinceridad... "decime, ¿cómo es que hacés eso? Quiero aprender". Así que les dedico la siguiente explicación:

Vamos al grano. ¿Qué hace falta?
Mi respuesta es: saber sumar, saber lo que es un número par, saber dividir por 2, saber las tablas del 7 (ni siquiera hace falta saberla completa), y tener la suficientes ganas de aprender esta técnica como para practicarla un poquito, porque, bueno, lleva un poco de práctica agarrarle la mano.

Y entonces, vos decime, ¿qué sumo?
Primero, se van a sumar unos cuantos números y al final vas a tener que hallar el resto de eso al dividir por 7 (o la congruencia módulo 7, como se le llama). En español: si te queda 71, como 70 es múltiplo de 7 (7*10) solo nos importa el 1 que sobra. Porque 71 = 70+1, entonces 71 = 1 (mod 7). Y dada esta característica del método, no hace falta sumar todos los números, sino que alcanza con sumar los mod 7 de cada uno.
Nota: se divide todo por 7 porque la semana tiene 7 días. Entonces el día 8 es lo mismo que el día 8-7 = 1. Etc.
Esta es una forma de agilizar un poco las sumas que hay que hacer mentalmente, ejemplo:

  • 71 + 14 + 5 = ummm ni idea
  • ah pero 71 es 1, 14 es 0, 5 es 5
  • entonces hago 1+0+5 y es lo mismo
  • 71+14+5 = 6 (mod 7)
Jajá, lo tengo en cuenta... pero decime qué tengo que sumar, ctm
Andando:

  1. Sumar el día. En 26 de septiembre de 1999, el "día" es "26"
  2. Sumar el código del mes. Cada mes tiene un valor asignado... solo hay que memorizarlo, no son muchos!
  3. Sumar el código del 'siglo'. Cada año comienza con 2 números: 1999 con 19, 2000 con 20, etc. Cada siglo tiene un código asignado, hay que memorizarlo pero es sumamente sencillo, son solo 2 números a efectos prácticos, salvo que quieran calcular fechas del año 1600 o por ahí, ahora lo explico.
  4. Sumar el 'valor del año'. Probablemente este sea el paso más trabajoso. Pero básicamente, consiste en lo siguiente: el 'año' son los dos últimos dígitos del año entero (1999=99, 2015=15, etc). Entonces el 'valor del año' se obtiene sumando el año + el año dividido 4, todo eso módulo 7. Puede resultar un poco complicado de calcular, pero hay algunos atajos. Ahora lo explico.
  5. Nota: Restarle 1 al resultado si el año es bisiesto y el mes es enero o febrero. Ojo con esto, casi nunca pasa pero existe el caso.
Entonces para 26 de septiembre de 1999, las sumas serían:
26 + código(septiembre) + código(19xx) + (99+99/4)
o lo que es lo mismo, todo mod 7, y reemplazando por los códigos (ya lo explico, aguantame!)

5 + 4 + 1 + (1 + 3) = 14 = 0
entonces como 0 = domingo, 1 = lunes, 2 = martes... etc, decimos que fue un domingo.
Nota: fijate que cambié 26 por 5 porque 26 = 21+5, y 99 por 1 porque 99 = 98+1 = 14*7 + 1, etcétera. Es más fácil para hacer las sumas mentalmente.

Bueno, eso se entiende, pero explicame los códigos que no entiendo nada.
Okey. Para los meses tenés que aprenderte esto (te dejo algunas reglas mnemotécnicas también):
Lo mejor es aprenderlo con práctica, y repitiendo. Realmente, no son muchas, son solo 12. Con algo de práctica y ganas se aprende.

  • Enero = -1 (enero es el primero, así que restamos 1. Nota: es lo mismo que sumar 6)
  • Febrero = 2 (como el número del mes)
  • Marzo = 2 (como su hermano febrero!)
  • Abril = 5 (como la cantidad de letras que tiene, ABRIL)
  • Mayo = 0 (la más fácil de sumar, porque no hay que sumar nada)
  • Junio = 3
  • Julio = 5 (igual que abril, la cantidad de letras que tiene JULIO)
  • Agosto = 1 (siempre me acuerdo esto como que es "a gosto", una sola 'a')
  • Septiembre = 4
  • Octubre = 6, o bien, -1
  • Noviembre = 2 (no! tiene 2 letras)
  • Diciembre = 4
A los que no le puse regla mnemotécnica es porque no tengo ninguna, simplemente me los acuerdo por práctica. Estás invitado a crear tus propias reglas.
Como vemos en el ejemplo anterior reemplacé septiembre por "4" porque es su código.

¿Y el código del año? No me veo haciendo todas esas cuentas...
Bueno. Antes yo había dicho que solo hacía falta saber dividir por 2 y saber cuando un número es par... Y creo que estamos de acuerdo que dividir por 2 no es algo que sea extremadamente difícil. Quizás hay algunos casos como 54/2 = 27 pero no es nada terrible. Así que:
Método más sencillo para obtener el código del año:

  1. Si el año es impar, restarle 1. Si no, nada.
  2. Dividirlo por 2.
  3. Repetir el paso 1 y 2.
  4. Sumar el año original + el resultado del paso 3, en módulo 7 si se prefiere, o los números completos, como quieras.
  5. Listo!
Ejemplo con 1957:

  • 57 => 56 (-1 porque es impar)
  • 56 => 28 (divido)
  • 28 => 28 (es par, no hago nada)
  • 28 => 14 (divido)
  • 57 + 14 = 1 + 0 = 1 (sumo todo en mod 7)
Con una mínima práctica, se puede hacer mentalmente. Pero bueno, no es el paso más fácil, estoy de acuerdo con eso.

Una pequeña nota sobre los años bisiestos:
Un año es bisiesto si sus dos últimos números son múltiplos de 4... Excepto que sean "00"... Excepto que el año sea 2000 (u otro múltiplo de 400, como 1600 o 2400 pero no nos importan mucho). Literalmente, esas son las reglas para años bisiestos. Súper extrañas. A nosotros solamente nos importa:

  • Si sus dos últimos dígitos son múltiplos de 4 y no son "00" es bisiesto (ej 1964, 2016)
  • Si es 2000 o 1600 o 2400 o cualquier múltiplo de 400, es bisiesto.
  • En todo otro caso, no es bisiesto (ejemplo: 2005 no es, 1900 no es, 1803 no es).
Entonces si estamos haciendo un cálculo con un año, y resulta ser bisiesto... al resultado final le tengo que restar "1" si y sólo si el mes es enero o febrero. Sino no hace falta.

¡Con esto ya estamos! Parece un poco largo, pero realmente es corto. Es decir, este programa hace todo eso y en solamente 3 (o 4, si se quiere) líneas:

def a(d,m,y):
    b=[0,6,2,2,5,0,3,5,1,4,6,2,4];c=[0,5,3,1];e=y%100;f=0
    if m<3 and y%4==0 and(y%100!=0 or y%400==0):f=1
    return(d+b[m]+c[y//100%4]+e+e//4-f)%7

Un poquito agolpado pero, realmente, eso es todo lo que describí recién. Es solo sumar 4 números y hallar el resto dividiendo por 7. Todo lo demás que escribí son ayudas para agilizar todo este tema cuando se hace mentalmente.

Tengo casi todo, me falta el 'código del siglo', wtf es eso?
Nada, es re fácil. Si el año arranca con 20xx, es "0". Si arranca con 19xx, es "1". Listo, eso nada más.

Peeero... si querés hacer cuentas más extremas, como en el año 1776, o en el futuro en el 2395, entonces te cuento un poco más (sentite libre de saltear esta parte si no te interesa):
Este 'código' sigue un período que es "1, 0, 5, 3", y se repite indefinidamente. Entonces, viene de la siguiente forma:
1600: 0
1700: 5
1800: 3
1900: 1
2000: 0
2100: 5
etc...
Así que solamente hace falta, o bien contar para adelante/atrás, o bien acordarse todos los valores para los siglos que te importen, o bien asociar que según los primeros dos dígitos mod 4 (20 = 0 mod4, 18 = 2 mod 4, etc), basta con fijarse qué número corresponde:
0 => 0
1 => 5
2 => 3
3 => 1

¿Por qué es útil saber la tabla del 7?
A la hora de calcular los 'módulo 7', no hace falta hacer toda la división ni nada... solamente, hay que pensar cuán cerca está el número del múltiplo de 7 menor más cercano. Con saber estos alcanza:
0
7
14
21
28
35
42
49
56
63
70
77
84
91
98
Los primeros son sumamente fáciles (0, 7, 14, vamos...), pero hay algunos que no son tan 'conocidos' como 98, u 84, incluso quizás no te suene el 63 o el 42... es bueno tenerlos frescos.

A continuación algunos ejemplos completos:


  • 31 de diciembre de 1977:
    • 31 + código(diciembre) + código(19) + (77+77/4)
    • 3 + 4 + 1 + (0 + 5) = 6, sábado.
    • Nota: el 3 y el 4 no los sumé, porque 3+4 = 7 = 0 (mod 7)
  • 14 de octubre de 2012:
    • 14 + código(octubre) + código(20) + (12+12/4)
    • 0 + 6 + 0 + (5+3) = 7 = 0, domingo.
    • Nota: sumar 5+3=8 es lo mismo que sumar 1.
  • 12 de junio de 1915:
    • 12 + código(junio) + código(19) + (15+15/4)
    • 5 + 3 + 1 + (1 + 3) = 6, sábado.
    • Nota: lo mismo, 5+3 es lo mismo que +1.
  • 4 de septiembre de 1998:
    • 4 + código(septiembre) + código(19) + (98+98/4)
    • 4 + 4 + 1 + (0 + 3) = 12 = 5, viernes
    • Nota: en este caso me pareció más fácil tomar 4+4 como +1 y hacer 1+1+3=5, salteándome el 12... a gusto de cada uno.
  • Para los atrevidos, 25 de febrero de 1778:
    • 25 + código(febrero) + código(17) + (78+78/4)
    • 4 + 2 + 5 + (1 + 5) = 3, miércoles
    • Nota: en este caso tomé 4+2 y 1+5 como ambos 6, o sea, como ambos -1. Entonces solo tuve que hacer 5-2 = 3.
  • 29 de febrero del 2000 (la mejor fecha de la historia):
    • 29 + código(febrero) + código(20) + (00+00/4)
    • 1 + 2 + 0 + (0+0) = 3... pero el 2000 fue bisiesto, le resto 1 = 2, martes!
    • Nota: es la mejor fecha porque fue el primer 29 de febrero (la mejor fecha) en un año con 3 ceros (el mejor año), en la historia de la humanidad.
  • 10 de mayo de 2019:
    • 10 + código(mayo) + código(20) + (19+19/4)
    • 3 + 0 + 0 + (5+4) = 12 = 5, viernes. Sí, hoy es viernes.
    • Nota: mañana es sábado pero hay clases igual. :c
Y bueno, eso es todo... Ahora solamente voy a describir, para los aventureros, cómo todo esto puede ser hecho incluso más rápido, y con menos cálculo mental... Aunque hace falta practicarlo muchísimo más. Bueno, acá voy:

Es posible memorizar el valor de año de los años entre el '90 y el 2019, para calcular las fechas más recientes en un abrir y cerrar de ojos. Además, sabiendo toda la década del '90 y los dosmiles, ya tenemos la fecha de nacimiento de mucha gente facilitada. ¿Alguna regla mnemotécnica? Sí, por supuesto. Te brindo del '90 a los '20, unos 40 años:

Algo a notar: el valor conforme aumenta el año, aumenta siempre en "1", salvo que se llegue a un año bisiesto, en ese caso se suma "2". Mirando un poco los ejemplos siguientes se puede razonar y entender bien:

los 90:

  • 90 = 0. Los primeros dos coinciden con su número final.
  • 91 = 1. Ves, te dije.
  • 92 = 3. Ahora, hasta el 96 tenemos que sumarle uno más a su último dígito nada más.
  • 93 = 4
  • 94 = 5
  • 95 = 6. Listo, tenemos más de la mitad ya.
  • 96 = 1. Estos se pueden aprender por repetición, son 4 nomás.
  • 97 = 2
  • 98 = 3
  • 99 = 4. Y este es el más útil, porque calcular el código de 99 mentalmente duele mucho.
los '00 y el 10 (súper fácil):

  • 00 = 0. Si es menor a 4, no podemos dividir por 4, así que queda el mismo número.
  • 01 = 1
  • 02 = 2
  • 03 = 3. Nada más que decir.
  • 04 = 5. A partir de ahora sí que podemos, así que solamente le sumamos 1.
  • 05 = 6
  • 06 = 0 (lo mismo que 7)
  • 07 = 1 (lo mismo que 8)
  • 08 = 3. Y bueno, acá es mejor aprendérselos, no cuesta nada.
  • 09 = 4. Este y el anterior.
  • 10 = 5. Acá pensamos que 5 es la mitad de 10 y ya está.
los '10:

  • 11 = 6. Hay una canción que se llama así.
  • 12 = 1. De acá hasta el 15 es como restar sus dos cifras, 2-1.
  • 13 = 2. 3-1, etc.
  • 14 = 3.
  • 15 = 4. Ya tenemos la mitad hecha.
  • 16 = 6. Se repite el 6.
  • 17 = 0. Es uno de los años "raíz", o sea que vale 0. ¡Es útil aprenderse las raíces!
  • 18 = 1. Me acuerdo porque viví este año hace muy poco.
  • 19 = 2. Es el año corriente.
los '20:

  • 20 = 4. Viene 4, 5 y 6 seguidos, sin mucha vuelta. A aprenderlos y listo.
  • 21 = 5
  • 22 = 6
  • 23 = 0. 23 es una raíz piola. Y la próxima viene pronto.
  • 24 = 2. De acá a la próxima raíz solamente es como restar sus cifras. 4-2.
  • 25 = 3. 5-2, etc.
  • 26 = 4.
  • 27 = 5.
  • 28 = 0. Llegamos a la otra raíz. Por supuesto, todos los múltiplos de 28 son raíces. (56, 84)
  • 29 = 1. Uno más que la raíz.
  • bonus: 30 = 2. Dos más que la raíz.
Y así se puede seguir. Lo conveniente, si ya se llega a este punto de desear memorizar los valores de cada año (son 100, por supuesto), es armar una lista y estudiarlos... O bien aprender las raíces y hacer cuentas en torno a eso... En fin, ya supone un esfuerzo, y no todos están dispuestos a enfrentarlo. Pero la herramienta está.

De ahora en más, la entrada anterior, del 9 de abril de 2014 (qué día fue? click) queda oficialmente obsoleta y la presente debe ser utilizada como referencia en su lugar.

Día.

miércoles, 1 de mayo de 2019

Éxito aquí

Cada tanto en esas clases entraba la señora con el teclado. Un teclado, digo, un piano eléctrico. El instrumento. Pedía permiso al docente, se asentaba en una mesa adelante de todo, observaba el panorama de la clase, y comenzaba a cantar. Su voz era bastante poco armoniosa, chillona, y a menudo mantenía esas notas agudas que generaban un murmullo en el aula, producto de una risa contenida en masa. Y como si eso fuera poco, sus hits estaban todos en una lengua extranjera que nadie del aula manejaba: el hebreo.

A lo largo de los años la misma señora se presentó de la misma manera en todos los cursos, incluso algunos dicen haberla visto en la terraza sola o en el vestuario de la pileta. Siempre saludaba afectuosa y cordialmente a los docentes, y se mostraba como una conocida. Pero nos quedamos en 'se mostraba'.

Un día, de tantos que existen en la vida de uno, se comenzó a rumorear que nadie conocía verdaderamente la proveniencia de la señora. Pues, se contaba que se escuchó a unas profesoras manteniendo una conversación similar a la siguiente:

+ "Che, ¿vos sabés quién es esa del piano?"
- "No, ni idea, pensé que la conocías."
+ "¿En serio? Yo pensé lo mismo. ¿Y quién es?"
- "Creo que nadie la conoce. Varias veces hablé con otras del área y todas la saludan porque las otras la saludamos nomás."
+ "Que raro..."

El rumor se hizo más extenso, pasando por todos los docentes, llegando a la jefa del área de historia (pues la señora del piano siempre entraba a las aulas de los docentes de historia), y ante tamaño misterio, esta pregunta llegó al mismísimo Director de la institución. Bueno, en realidad el rumor del esparcimiento del rumor de la señora del piano era otro rumor.

Pasó un tiempo... No se produjo ningún avistamiento de la señora del piano por unos meses. Pero eso era habitual, no estaba por todo el año interrumpiendo las clases de historia.
Hasta que me pasó esto.

Me había dormido muy temprano el día anterior, y entonces terminé despertándome más temprano que de costumbre. Como no tenía nada para hacer, me fui a clases bien bien temprano. Total, abrían las puertas como hora y media antes de la primera hora.
Llegué, bien temprano, de hecho antes que nadie, y me quedé esperando en la puerta hasta que abrieran, para poder entrar. En todos los años que había asistido allí, nunca había oído de nadie, ni de nadie que hubiera oído de nadie más, que hubiese llegado tan temprano como para esperar afuera. Creo que fui uno de los primeros en hacer eso, sino el primero.

Ya faltando 90 minutos para la primera hora (había llegado unas 2 horas antes), se abren las puertas, desde adentro. Me llamó muchísimo la atención, porque esto significa que ya había gente adentro, o que entraron por otra entrada, aunque yo no conocía ninguna otra además de la principal. Supuse que habría otra entrada.

Cuando entré, el lugar estaba completamente desierto. Ni siquiera había alguien que pudiera haber abierto la puerta. "Bueno, cerradura electrónica o algo", pensé.
Ya que era tan temprano, pensé caminar un poco por el colegio, total, no tenía nada para hacer, y bueno, ya fue.

Así que subí las escaleras, me propuse ir hasta el lugar más recóndito en la hora más insólita, solo como un 'logro desbloqueado' para mí mismo. Estaba, repito, sin nada mejor para hacer.
Entonces pensé subir a la terraza. Siempre había visto una puerta que conducía a algún lugar al que nunca había logrado entrar, y pensé aprovechar la situación para echarle un vistazo.
Llego al piso número seis, hago un pequeño paso de parkour para saltar por un hueco y ver si podía abrir la puerta desde ahí. Era como un mostrador o una barra extraña que había ahí, no sabía bien por qué... Hasta ese momento.

Debajo de la barra había una tapa, en el piso. No sé qué se me cruzó por la cabeza, que se me ocurrió levantarla a ver qué había debajo.

Al hacer eso, yo esperaba ver cablerío, o bien algunos caños, una rejilla... Pero no... Veo una escalera vertical que descendía unos metros para abajo. Curioso, pues, este era el último piso para arriba; no suele haber sótanos en la terraza...

Y bueno, qué más da... Descendí. Con cuidado dejé la mochila, iluminé un poco para ver si había algo que pudiera salir mal, y con un poco de imprudencia simplemente me metí en el agujero.
Tras descender unos 5 metros, me encontraría en una especie de entrepiso entre el piso 4to y 5to. Y hasta el día de hoy no puedo creer lo que vi.

Era un salón gigantesco, que ocuparía todo el piso de ese ala del edificio, sin ninguna pared en el medio, con un techo de una altura de cerca de 120 centímetros. Ahora me hacía mucho sentido por qué los pisos tenían tantos escalones entre ellos... Existían entrepisos muy amplios, quién sabe para qué.
Pero este no era un entrepiso cualquiera.
Estaba lleno,
completamente lleno
de teclados eléctricos.

Tenía una iluminación muy tenue, que venía principalmente del hueco por el que había bajado. Ya con un poquito de miedo (qué digo, estaba cagado) encendí la linterna de mi teléfono celular para ver mejor.
Ni bien se encendió el LED, que demora aproximadamente 0,7 segundos desde que se presiona el botón, me estremecí completamente y sentí escalofríos como si la temperatura hubiese descendido a -15 grados centígrados.

En el fondo del salón, bien allá lejos, estaba la señora. Quiero decir, yo pensé en algún momento de mi travesura que la señora podría haber estado allí múltiples veces, que utilizase eso como espacio de almacenamiento. Pero nunca, nunca, me esperaba verla allí... En su cama.

Por supuesto apagué inmediatamente la luz, pero lo que pude ver era una cama, al fondo de la sala, un velador al lado de la cama, una pila de libros, muchísimas partituras, y muchísimos, INNUMERABLES teclados rotos, y algunos sanos.

Escuché un movimiento, como si hubiese despertado a la señora, pero inmediatamente salí corriendo, subí por la escalerita, me raspé un poco las manos sin querer, puse la tapa, y rajé súbitamente de ese lugar.
Me fui lo más lejos que pude, yendo al comedor que estaba en la planta baja, esperando que la señora no bajase... Pues, yo seguía siendo el único que estaba en todo el lugar.

Afortunadamente eso no sucedió, y después de una hora comenzó a llegar más gente. El día siguió con normalidad.

---

Hasta el día de hoy, no me había animado a contarle esto a nadie. ¿Qué significaría lo que ví? ¿Cuánto tiempo hacía que la señora estaba en ese sótano de un metro 20 de altura? ¿Cómo podía ser que alguien viviera así? ¿Era acaso legal? ¿De dónde vino, y hacia dónde iría la señora? Demasiadas preguntas que nadie podría contestar, demasiadas preguntas que nadie debería plantearse nunca.

Pero hoy, ya varios años después de que yo terminara de cursar en ese lugar, me animo a contarlo...

Espero que no desate la catástrofe.

Sinceramente,
                       yo.