Regístrate | Conectar
El Tamiz Libros Recursos Series Únete 20 Users Online
Skip to content

Resolviendo “Cifras y Letras” (y… IV?)




Hace ya cinco años largos[1] que publiqué tres artículos explicando mi antigua fascinación por el concurso televisivo “Cifras y Letras” (originalmente Des chiffres et des lettres, ya que es un concurso inicialmente originado en Francia), y qué soluciones había ido creando para que un programa informático pudiera encontrar de forma óptima o casi óptima la solución para los problemas de cifras. Y había yo quedado muy satisfecho porque, tras interesantísimas discusiones con los lectores, había llegado, creía yo, a una solución elegante y óptima, o todo lo cerca de óptima que puede ser la solución a un problema NP-duro, como cruzki, un inveterado seguidor del Cedazo, tuvo a bien explicarnos.

Pues bien, hace unas pocas fechas Valero, en un comentario, desmontó de un plumazo parte de mi sesuda teoría para la resolución del problema, haciéndome ver en concreto que descartar una posible fórmula cuando produzca un resultado intermedio fraccionario podía acarrear no encontrar solución a un problema que en realidad sí que la tiene… Y, claro, un Viejo Informático cascarrabias y terco como una mula, como es mi caso, no podía dejar así las cosas, así que vuelvo al tema una vez más, y espero que ésta sí sea la última, para determinar el método-más-o-menos-óptimo para resolver los problemas de cifras de “Cifras y Letras”.

Pero antes, un poco de historia para los que no estuvieran por aquí en 2011… o los que sí, pero que no se acuerden, como sería mi caso… ;)

Uno de tantos juegos sobre las cifras…

Si ya sabes de qué va ese concurso puedes ahorrarte este párrafo y los dos siguientes. Cifras y Letras, que se empezó a emitir en España en 1991, es un programa televisivo que consiste en plantear pruebas a dos concursantes que compiten entre sí, pruebas que tienen que resolver en un tiempo dado, 45 segundos en España, y que son de dos tipos: de letras, en las que se proponen de forma más o menos aleatoria nueve letras y gana la prueba el concursante que con dichas letras compone una palabra válida más larga; y de cifras, en las que se proponen seis números como argumentos más un séptimo número objetivo. La prueba consiste en, usando los seis números iniciales, pero sólo una vez cada uno (está prohibido usar más de una vez un cierto número), y operando con ellos mediante las cuatro operaciones básicas, suma, resta, multiplicación y división, obtener el número objetivo dado. Gana la prueba el concursante que consigue el objetivo exacto o, en su defecto, si ninguno de los dos lo logra, quien más se acerque.

Los números que se proponen para conseguir el objetivo no son unos cualquiera, sino que están limitados a estos 14 valores: del 1 al 10, el 25, el 50, el 75 ó el 100. En cuanto a los objetivos, son siempre mayores que cien y de tres cifras, es decir, están comprendidos entre 101 y 999, ambos inclusive. Eso quiere decir que siempre es necesario usar al menos dos números para obtener el objetivo exacto, como sumar 100+7 para obtener un hipotético 107 como objetivo.

Por ejemplo, dados los siguientes seis números: 7, 75, 25, 1, 7 y 5, y el 932 como objetivo, se puede obtener el resultado exacto de la forma siguiente: 5×7=35; 35-1=34; 34×25=850; 850+75=925; 925+7=932. ¡Exacto, usando todos los números! O también se puede llegar usando sólo cinco de ellos de la siguiente forma: 7+5=12; 12×75=900; 900+25=925; 925+7=932. El 1 no ha sido necesario en este caso. Sin embargo, siendo el objetivo, por ejemplo, el 380, y los argumentos 1, 3, 4, 9, 9 y 9, no hay forma de llegar al objetivo exacto. Lo más cercano es llegar a su vecino 379: 9+9=18; 18-4=14; 3×9=27; 27×14=378; 378+1=379. No se puede conseguir el 380 con estos números iniciales.

.

Volvamos, entonces, al relato: publiqué, efectivamente, tres artículos en aquella serie. En el primer artículo lo primero de todo explicaba someramente cómo atacar informáticamente los problemas de letras, aunque sin llegar a realizar la solución (es bastante trivial, siempre que se disponga de un diccionario con las palabras admitidas como válidas), pero como lo realmente interesante y divertido es resolver los problemas de cifras, allí explicaba cómo atacar el problema por fuerza bruta, es decir, realizar todas las posibles combinaciones de operandos y operaciones para intentar llegar al objetivo. Y la cosa no es baladí, porque combinar seis números entre sí usando las cuatro operaciones elementales puede hacerse de nada menos que ¡30.965.760 maneras, es decir, fórmulas, distintas! Si te parecen muchas, puedes ir a ese primer artículo de la serie y ver por qué son tantas. Por lo tanto, realizar un ataque por fuerza bruta consiste en comprobar todas y cada una de los casi 31 millones de fórmulas posibles hasta lograr alcanzar el objetivo, bien como resultado final de la fórmula, bien con un resultado intermedio, ya que no es obligatorio usar los seis números para obtener la solución exacta.

En realidad éste no es un problema informáticamente difícil de resolver, pero, claro, obtener la solución puede tardar mucho, sobre todo en determinar que no hay solución,[2] así que un buen informático (al menos si es uno del Pleistoceno) intentará buscar cómo obtener los mismos resultados pero haciendo muchísimas menos operaciones… y a eso dediqué el segundo artículo de la serie, a explicar el proceso de optimización que había seguido para conseguir: 1) minimizar el número de fórmulas a probar, así como 2) minimizar el número de operaciones a realizar en cada fórmula. Resumo todo esto brevemente.[3]

Para reducir drásticamente el número de fórmulas a probar, (1), lo que hice fue localizar fórmulas que, siendo en apariencia distintas, son en realidad la misma fórmula, y quedarme con solamente una de ellas, descartando todas las demás. Por cierto, en lo que sigue usaré los números 1-2-3-4-5-6 como variables para denotar los seis números argumento, es decir, cuando diga “1+2” no quiere decir “3“, sino el resultado que daría sumar el primer argumento con el segundo, sea cual fuere su valor. Bien, veamos un ejemplo para ilustrar dos fórmulas que, siendo aparentemente distintas, son en realidad la misma: [(1+2)x(5+3)]/(4+6) y [(3+5)x(2+1)]/(6+4). Efectivamente, la propiedad conmutativa de la suma y la multiplicación nos indica que (1+2) dará siempre el mismo resultado que (2+1), sean cuales fueran los valores concretos de los argumentos 1 y 2, y lo mismo con el resto de sumas y productos: (1+2)x(5+3) dará exactamente el mismo resultado que (3+5)x(2+1), etc. Lo que no se puede hacer es, obviamente, cambiar el lugar de la división, porque ni ésta ni la resta son conmutativas. Por eso, (4+6)/[(1+2)x(5+3)] es una fórmula distinta a las dos anteriores y no se puede descartar por este motivo.

En fin, aplicando una serie de reglas sucesivas para eliminar fórmulas redundantes conseguí dejar reducidos los cerca de 31 millones de  fórmulas distintas a un conjunto equivalente de solamente 1.025.472 fórmulas diferentes, apenas un 3,5% de las combinaciones originales y que, tras muchas pruebas, millones de ellas, puedo asegurar con un 99,999% de certeza que se comporta como el original de 31 millones: cuando no encuentra solución a un problema, es que no la tiene. En ese segundo artículo explico en detalle el proceso seguido.

Luego, en comentarios, Antonio Villena sugería ciertas mejoras posibles al algoritmo; la más interesante y obvia era ordenar de menor a mayor los seis números argumento antes de pasárselos al proceso. De esta forma, tras una serie de transformaciones y eliminaciones, las 1.025.472 fórmulas del fichero de combinaciones a comprobar quedaron reducidas a solamente 488.642 fórmulas, menos de la mitad y apenas un 1,5% de las fórmulas originales. Todo este proceso lo expliqué en el tercer artículo de la serie.

Bueno, vale, de acuerdo: aquí los más atentos se habrán dado cuenta de una cosa: ¿por qué demonios ordenar los argumentos puede reducir el número de fórmulas a probar? ¿Qué más dará cómo vengan ordenados los valores de los argumentos para que una fórmula se pueda descartar como duplicada o no? Y, claro, tenéis razón, pero es que aquí entra la segunda pata del proceso de optimización (2) que antes comentaba, tratando de minimizar el número de operaciones a realizar al probar las fórmulas. Y eso.. ¿cómo es posible? Pues, durante el proceso de resolución, descartando la fórmula  en cuanto al operar se obtenga un valor ilegal. Y valores ilegales son o bien los números negativos o cero o bien números no enteros. Es decir, si en el cálculo de una fórmula se obtiene un resultado intermedio negativo o cero como consecuencia de una resta, o bien uno no entero como consecuencia de una división, se puede descartar en ese momento la fórmula sin probar el resto de operaciones que falten, porque seguro que no nos sirve o, en el caso de que sí nos sirviera, porque siempre habrá otra fórmula en el fichero que dará el mismo resultado sin obtener ninguno de estos números intermedios ilegales.[4] La reducción en cálculos innecesarios era tremenda: empíricamente constaté que las operaciones que nos evitábamos hacer debido a este truquito eran aproximadamente ¡un 47%!… Fantástico, ¿no?

Y, cabría preguntarse,  ¿por qué es posible descartar una fórmula dada si obtiene alguno de esos valores “ilegales“? Vayamos por partes:

La base para tal afirmación para el cero es evidente: si un resultado parcial es cero, por ejemplo por calcular (25-25) en cualquier momento de la resolución, es como si no se hubiera operado con esos argumentos, por lo que cualquier otra  fórmula que use el resto de argumentos del mismo modo obtendría el mismo resultado sin obtener dicho cero en ningún momento. En cuanto a por qué descartar los números negativos, la explicación es también sencilla: si en el proceso de cálculo de una fórmula se obtiene un valor negativo, la única forma de llegar a obtener el objetivo exacto, que es positivo, es o bien multiplicar dicho número negativo por otro número negativo, o bien sumarle a otro más grande o restarle de uno positivo. En ambos casos es fácil ver que existirán en el fichero de fórmulas a probar alguna o algunas otras, diferentes de la probada, que darán el mismo resultado sin obtener negativos. Por ejemplo, se puede obtener el resultado 300 con la fórmula (3-7)x(25-100), es decir, -4x-75=300, pero podemos estar seguros de que la fórmula que origine el cálculo (7-3)x(100-25) está también en el fichero de combinaciones a probar: da el mismo resultado, 300, pero sin negativos entre medias. Y parecida lógica puede usarse para el caso de sumas y restas solamente: (3-7+25) da lo mismo que (3+25-7), que llega al mismo resultado, 21, sin necesidad de pasar por el -4 que se genera en la primera fórmula.

Entonces, cuando los argumentos vienen ordenados, es decir, 1 ≤ 2 ≤ 3 ≤ 4 ≤ 5 ≤ 6 (recuerdo una vez más que aquí 1, 2, 3… no son los valores 1,2, 3, etc, sino los valores de los argumentos primero, segundo, etc), entonces podemos descartar a priori aquellas fórmulas que sabemos de antemano que darán un resultado negativo o cero. Por ejemplo, si aparece la combinación (1-4) en una fórmula cualquiera podemos estar seguros de que el resultado de esa operación será negativo o cero porque, al venir ordenados, el argumento 4 es mayor o igual al argumento 1, y restar un número de otro menor o igual seguro que da un valor negativo o, como máximo, cero.

Y sobre los números fraccionarios lo mismo, ¿no? Si una división da un resultado no entero, para poder llegar al objetivo final, que sí lo es, no queda más remedio que multiplicarlo más adelante por otro valor múltiplo del divisor que dio un valor no entero, por lo que existirá con toda seguridad una fórmula diferente que altere el orden de los cálculos para evitar los decimales, ¿no? Por ejemplo, 100+(5/2)x8 da 120, pero obtiene un 2,5 intermedio debido a la división de 5 entre 2… seguro que encontraremos otra combinación que obtenga el mismo resultado sin decimales, y la hay, claro: 100+(8×5)/2 llega a la misma conclusión, 120, sin valores no enteros en los resultados intermedios. Luego la deducción es correcta: se pueden parar los cálculos si obtenemos cualquier resultado intermedio fraccionario, eso es seguro, segurísimo, ¿no? Y por tanto, se pueden descartar aquellas fórmulas que sepamos seguro y de antemano que van a obtener un número fraccionario menor que cero o uno… Por ejemplo, si una fórmula contiene el cálculo (1/5) podemos descartarla de antemano, porque como el quinto argumento es mayor o igual que el primero, el resultado será bien un número fraccionario menor que uno, o bien, en el mejor de los casos, uno, si ambos números son iguales. Si da uno, como sabemos que también estará la fórmula idéntica pero haciendo (5/1), que da el mismo resultado en este caso, podemos olvidarnos de ella. Y si diera un número menor que uno, como 0,166666… o lo que sea, podemos también descartarla, que ya lo hemos probado antes sin género de dudas, ¿no? … ¿NO?

PUES NO!!

En este caso, contra lo que podría parecer en ese juicio apresurado, es posible plantear un problema que exija para su resolución pasar por un resultado intermedio que sea un número no entero. Por ejemplo, obtener el 911 con los números 1, 2, 2, 3, 50 y 75 es imposible descartando los resultados no enteros. Sin embargo, sin descartarlos, resulta que el problema sí tiene solución, una única forma de obtenerla… una forma de operar que tiene su guasa. Atentos:

75/2=37,5;

37,5-1=36,5;

36,5×50=1825;

1825-3=1822;

1822/2=911. El exacto.

Efectivamente, es necesario pasar por el 37,5 y el 36,5 para llegar a obtener el objetivo marcado, el 911, que de otra forma es inalcanzable. El motivo, ahora que se ve en el ejemplo, es obvio: efectivamente, como decía antes, para obtener un objetivo entero pasando por un resultado no entero es preciso multiplicar el resultado por un número múltiplo del divisor en un paso posterior. En el caso anterior, tras dividir por 2, luego, en un paso posterior de la fórmula, se multiplica por 50, que como es múltiplo de 2… pues es como multiplicar por 25 el número original, pero con un pequeño detalle: antes de multiplicar por ese 50, el resultado parcial no entero ha sido modificado por una suma o una resta, por lo que el resultado del producto ahora varía. La operación realizada en este caso para conseguir el exacto es [(75/2)-1]50=1825. Esto es lo mismo que (7550/2)-(1×50), que daría el mismo resultado, 1825, sin pasar por resultados no enteros… pero ésa no es una fórmula válida, porque necesita usar dos veces el 50, lo que está prohibido.

En resumen, nuestro lector Valero tiene toda la razón, y descartar alegremente los resultados intermedios con decimales imposibilita la resolución de ciertos problemas que en realidad sí que la tienen. Otra cosa es que las reglas del programa televisivo, el citado Cifras y Letras, permitieran obtener resultados fraccionarios o no, aunque viendo las complicadas operaciones que habría que hacer para conseguir el exacto con números no enteros, y en 45 segundos… pues no es humanamente posible, me parece a mí.

La duda que queda es… ¿pero de verdad hay muchos casos en que ocurra esto? Es decir, ¿merece la pena andar cambiando programas y, lo peor, rehacer todas las transformaciones citadas en el tercer artículo de la serie, las que convertían el fichero original de 1.025.472 fórmulas en  uno mucho más pequeño de solamente 488.642? Si son muy pocos casos adicionales los que tienen solución, y viendo lo alambicada que es la forma de obtener el 911 de antes, se puede colegir que no habrá muchos, quizás no merezca la pena andar cambiando nada…

Bueno, podría haberlo dejado aquí, peroooo… va a ser que no. Mi ADN de informático de la vieja escuela me obliga a saber qué implicaciones tendría esta modificación al proceso: ¿Cuántos problemas que antes no tenían solución descartando fraccionarios sí que la tienen al no descartarlos? Tengo que saberlo, no puedo quedarme con la duda… así que me puse a ello. Y estos son los resultados obtenidos:

El número total de problemas posibles son 24.391.668, puesto que son en total 27.132 posibles combinaciones de números argumento[5] para obtener 899 objetivos posibles.[6]

Descartando resultados no enteros, habíamos encontrado hace cinco años 4.704.209 problemas que no tenían solución, algo más del 19% de todos los problemas. Hay que tener en cuenta que hay un cierto número de combinaciones de argumentos de esas 27.132, 51 en concreto, que no alcanzan a ningún objetivo válido, como por ejemplo la 1,1,2,2,2,8, que al objetivo más alto que alcanza es al 100 que, aunque por poco, no es un valor válido, y hay otras combinaciones más que sólo llegan a unos pocos objetivos, como la 1,1,1,1,1,25, que sólo alcanza a 5 posibles objetivos válidos: 101, 102, 104, 125 y 150, o peor aún, la 1,1,2,2,3,4, que sólo alcanza a componer un objetivo válido, el 108. Hay en total 13 combinaciones posibles de números que sólo llegan a un único objetivo válido. Todo esto no va a cambiar por permitir números fraccionarios.

Pues bien, manteniendo los resultados intermedios fraccionarios se obtiene solución para ¡438.034 problemas adicionales! El número de problemas que continúan sin solución ha descendido a 4.275.166, el 17,5% del total. Es decir, alrededor de un 1,76% de problemas sólo tienen solución si se admiten los resultados intermedios no enteros. Por ejemplo, llegar al 154 con los números 3, 3, 3, 6, 6 y 7 sólo se consigue de la forma siguiente:

3×3=9;

6/9=0,6666…;

0,6666…+3=3,6666…;

3,6666…x6=22; y

22×7=154, es decir, [(6/3x3)+3]x6x7. Pues como ésta, y como la anteriormente citada, 438.034. ¡Quién lo iba a decir!

Al eliminar la restricción de descartar los números no enteros, resulta que aparecen 422 nuevas combinaciones de números de las 27.132 totales que alcanzan a componer todos los objetivos posibles, los 899. Por ejemplo la 1,2,3,4,8,100, que antes alcanzaba a componer todos los objetivos menos el 946, y ahora sí que lo alcanza. Veamos cómo:

3/8=0,375;

2+0,375=2,375;

2,375×100=237,5;

237,5-1=236,5;

236,5×4=946.

He aquí cómo el programa encuentra sin despeinarse la solución para ese imposible 946.

Sorprendente, ¿no? Desde luego, esta solución sólo la puede encontrar un incansable programa de ordenador con un buen programa de resolución, porque un humano… y en 45 segundos… pues va a ser que no.

Y en cuanto a los objetivos, en todos ellos sin excepción se incrementa el número de combinaciones que ahora alcanzan dicho objetivo exacto.[7] Sigue siendo el 150 el objetivo que es más fácil de obtener: en 26.941 combinaciones de números posibles de las 27.132 totales es posible alcanzar el 150; teniendo en cuenta que hay 51 combinaciones que no permiten alcanzar ningún objetivo válido, eso quiere decir que solamente 140 combinaciones “útiles” no llegan a componer el 150. Y por el otro lado, el número objetivo más difícil de conseguir es el 967, que ya lo era con el cálculo descartando números no enteros, pero ahora hay bastantes más combinaciones que sí llegan al 967: con la formulación anterior había 12.809 combinaciones que no servían; ahora hay 12.296, es decir, hay 513 combinaciones de números que son capaces de alcanzar el 967 exclusivamente gracias a la obtención de números fraccionarios…

.

En fin. Es curioso ver cómo asunciones que se hacen con toda tranquilidad tomando como ciertas algunas cuestiones evidentes son luego refutadas de medio a medio por alguien más clarividente o más informado… claro que es así, precisamente así, como avanza la ciencia.[8] Si no fuera por ciertos personajes que continuamente se plantean si las cosas que son así son verdaderamente así, todavía estaríamos pensando que el Universo  se compone de tierra, aire, agua y fuego. O que la Tierra es plana… aunque, mmmm, ahora que lo pienso… ¿de verdad no lo es? ;)

Gracias, Valero.

 

  1. ¡Cómo pasa el tiempo, rediez! []
  2. Si no hay solución se habrían realizado algo menos de 155 millones de operaciones, los casi 31 millones de fórmulas por cinco operaciones en cada una de ellas. Esos son bastantes millones. []
  3. Si queréis ver el proceso completo, mejor ir a dicho artículo. []
  4. Ya anticipo que el comentario de Valero que citaba antes desmontó parcialmente esta suposición que tan sesudamente hice hace cinco años… luego lo explico, un poco de paciencia. []
  5. Cada problema consta de seis números de catorce posibles: combinaciones con repetición de 14 elementos tomados de 6 en 6. Es decir: (m+n-1)! / (m-1)! n!, o sea, 27.132. []
  6. Del 101 al 999, 899 valores diferentes. []
  7. Esto es lógico, si pensamos que hay 899 objetivos plausibles y más de 400.000 nuevas soluciones. []
  8. Y no estoy diciendo que toda esta diatriba que he soltado sea “ciencia”, que conste. []

Sobre el autor:

Macluskey ( )

Macluskey es un informático de los tiempos heroicos, pero no ha dejado de trabajar en Informática y disfrutar con ella hasta la fecha. Y lo que el cuerpo aguante. Y además, le gusta la música...
 

{ 17 } Comentarios

  1. Gravatar Eagle | 22/01/2017 at 12:08 | Permalink

    No esperaba menos de un viejo informático que resolver sus dudas porque sabe que puede hacerlo.

    Y por otro lado, todos los programas que hacemos tienen errores precisamente porque asumimos como verdades absolutas ciertas premisas que luego resultan no serlo. Un simple “este caso no se va a dar nunca” da para muchos errores, jeje. Pero bueno, suelen ser casos límite. Si tuviésemos que analizar todos los casos posibles los programas se entregarían con meses de retraso, y mientras sean válidos para el 99% de las ocasiones, es un daño aceptable (para según qué sean, claro, si hay vidas en juego no es ninguna broma).

  2. Gravatar Macluskey | 22/01/2017 at 07:48 | Permalink

    Ayyyyy, cómo me conoces, amigo Eagle… :)

    Pues sí, claro. Tienes razón. Los casos límite son los que arruinan cualquier cualquier programa “bien hecho”. El problema que veo yo en los programas de hoy en día es que nadie prueba un solo caso límite de nada. Eso cuesta dinero, y teniendo en cuenta que los programas actuales los hace en un 90% la subcontrata más barata… no pretenderás encima que estén bien probados, ¿no? ;) ;)

    En fin, c’est la vie, mon ami. Pa esto hemos quedado los viejos informáticos…

  3. Gravatar Isangi | 25/01/2017 at 05:53 | Permalink

    Hola, hace tiempo que soy lector de el tamiz y el cedazo, y leyendo este artículo me he acordado de un problema que quizá me podeis ayudar a solventar…

    Mi mujer se está iniciando en el mundo de la tecnología, informatica, programación, gestión documental, etc

    Y claro, aunque me he negado a enseñarle(ya sabeis, muy dificil tener de profesor a alguien cercano), si le voy guiando sus pasos hacia donde yo creo que le será útil, y hay algo que por más que le doy vueltas, no se como enfocar, me explico:

    Algo que es muy valorado en informática, y en casi cualquier trabajo, es tener esa capacidad yo diria que “Ingenieril” de solventar problemas, pero no solo solventarlos, sino a veces, simplemente, encontrar su origen, su causa o incluso descartar que sea culpable uno u otro, y eso, quizá con enfoques diferentes, se puede aplicar a casi cualquier situación, puede ser un codigo que da problemas o que hace fallar el programa o una maquina ensobradora que se atasca,…, no se si llego a explicarme.

    Claro, una buena parte de eso te lo da la experiencia, pero se que no es solo experiencia, y no se como conseguir que aprenda eso, sobretodo sin que tenga que pasarse 10 años aprendiendolo.

    Le puedo hablar del divide y vencerás, de probar valores maximos, minimos e intermedios, etc etc, pero se me sigue haciendo muy cuesta arriba conseguir escribir algo que le sea realmente útil(o encontrar algún libro que lo sea).

    Y aquí, viendo a MAcLuskey y otros expresarse bien y resolver problemas, se me ocurre que podeis ayudarme orientarme, recomendarme(a mi y a ella) lecturas, etc…

    GRACIAS!!!

  4. Gravatar Macluskey | 26/01/2017 at 11:52 | Permalink

    Gracias, Isangi, por la confianza, pero no sé muy bien cómo ayudarte.

    Tienes razón en tu demanda. Desgraciadamente tienes razón, porque actualmente no se valora casi nada esa actitud “ingenieril” como tú mismo la denominas. Lo importante es terminar lo antes posible, de la forma más barata posible, y dejarlo todo para la “versión 2″, o como dicen algunos albañiles, “tente mientras cobro…”.

    En mis tiempos eso no era así. Las capacidades de las máquinas eran escasísimas, la mano de obra, barata, y además éramos plantilla de la empresa, con lo que teníamos mucho cuidado en hacer las cosas lo mejor posible para facilitarnos el mantenimiento posterior. Justo lo contrario que ahora, donde se intenta que el mantenimiento sea complicadísimo para cobrar muchísimo por él.

    No sé qué recomendarte. Lo obvio sería decirte que se leyera mis “Memorias de un Viejo Informático” por si se le enciende la bombilla, pero seguro que esa opción ya se te ha ocurrido. No sé. Quizás decirle que piense antes de escribir una línea de código que “Cómo haría yo este programa (o lo que sea) si fuera yo quien tuviera que utilizarlo cada día“. O “si fuera yo quien lo pagara“, que es casi lo mismo. Porque cuando eres usuario se te ocurren mil maneras de mejorar lo que ha escrito algún becario de la contrata más barata… pues aplicarse el cuento al software que uno escribe.

    …Y estar muy atento a las opiniones de los usuarios finales. Harto estoy de escuchar a colegas eso de “este usuario no tiene ni idea (porque el que de verdad sabe lo que ese usuario necesita soy yo, no él)”. Pues, señores, eso es mentira en el 99,9% de los casos, y sólo tenemos que pensar lo complicado que es cambiarle el paso a los informáticos: “A ver si va a venir uno de Massachussets a decirme a mí, precisamente a mí, cómo hacer mi trabajo”… y lo dice tan pancho, dos minutos después de asegurar que su usuario no sabe hacer su trabajo.

    Pues eso: mucha humildad y preguntarse siempre “¿¿¿cómo querría yo que funcionara este sistema si fuera yo quien lo pagara???”. Aunque eso no te garantice que no te echen de la empresa subcontratista por no hacer las cosas bien… o sea, deprisa y mal, para poder cobrar luego una fortuna por mantenerlo. Así están las cosas, por desgracia para la profesión.

    Espero haber ayudado, por poco que sea.

    Saludos

  5. Gravatar Isangi | 27/01/2017 at 12:18 | Permalink

    Gracias Macluskey!

    Pues a pesar que he leido la parte de las “memorias” publicada aquí hace ya un tiempo y no caí en añadirlo a “lecturas recomendadas para mi mujer”… ¿tenias una versión completa a la venta en algun lugar verdad? (si, estoy seguro soy capas de encontrarlo solito por esta web,…, jejeje)

    Bueno, yo he visto de todo, pero si la tendencia actual es a poner parches y no a hacer “sistemas consistentes”, y para ejemplo la antigua empresa donde trabajaba, donde el jefe se creyó que el dpto. de informatica no tenia dificultad alguna y fácilmente sustituible(cuando es una parte troncal de la empresa(impresión personalizada de gran producción)), por coincidencias marchamos 2 de los 3 informaticos casi a la vez(el jefe del dpto y yo),…, ahora tienen el doble de plantilla, el doble de problemas y nos pagan a los dos para que les solventemos problemas a distancia y formemos a los que han contratado… Les ha salido barato… (y mientras, estoy hablando de meses, ya se han cargado al primer sustituo de mi jefe y están buscando al segundo).

    Un amigo tambien me ha dado pistas, así que para aportar algo a la web: a) Obviamente, programar y practicar mucho que se aprende. b) Pasarle ejercicios con programas nuestros, expresamente con errores que se nos ocurran(e ir incrementando la dificultad de esos errores). c) Pasarle problemas nuestros del pasado ya solventados o incluso algunos de los problemas que me contrata mi antigua empresa.

    aún así, sigo buscando ideas que puedan “acelerar el proceso” y sobretodo ampliarlo fuera de la programación propiamente.

    p.d.: lo de tratar al usuario final como tonto, en mayor o menor medida, creo que lo hemos hecho todos…, aunque no estoy del todo de acuerdo con tu 99,9%,.

  6. Gravatar Isangi | 27/01/2017 at 12:20 | Permalink

    Obviamente ya he encontrado tu libro en Kindle,..

  7. Gravatar Macluskey | 28/01/2017 at 01:49 | Permalink

    Hola de nuevo, Isangi.

    Pensando un poco sobre tu cuestión, se me ocurre que una forma de introducir a alguien en el proceloso mundo de la lógica informática puede ser proponerle un problema sencillo desde el punto de vista conceptual, o sea, que se entiende muy bien (el problema a resolver) y pedir al sujeto que piense cómo lo podría resolver informáticamente. Y luego ir atornillando más y más la solución para irla mejorando paulatinamente. Así me fueron enseñando a mí hace centurias.

    El capítulo del Sort de mi serie explica precisamente ese proceso son un problema bien conocido: el de la ordenación de listas. Pero es un problema bien conocido, así que quizás no sea lo bastante “nuevo”…

    Así que me parece que un buen comienzo puede ser precisamente el de construir una solución informática para resolver este concurso de Cifras y Letras: las dos pruebas, la de cifras y la de letras, tienen una definición clara, sencilla y no ambigua, y sin embargo su resolución contiene tantos matices, y se pueden ir mejorando por pasos de forma paulatina, que pueden ser un buen ejercicio para irse curtiendo en el pensamiento “ingenieril” que pedías. Que no lea la solución, ninguna de ellas, claro, sino que piense por sí misma cómo se podrían resolver ambos problemas… ¡y si encima hace el programa para resolverlo, mejor que mejor!

    No sé si es una idea estúpida, pero por probar…

  8. Gravatar Jefe Ryback | 30/01/2017 at 11:54 | Permalink

    Menudo pedazo de artículos fueron en su momento tus análisis del cifras y letras y el programa para solucionarlo. Y con este regreso de las brumas del tiempo desmientes a los que dicen que nunca segundas partes fueron buenas. XD

    El caso es que nunca estuve muy de acuerdo con plantearlo por “pseudo-fuerza bruta” como hiciste tú. Es una forma tan válida como obvia de hacerlo y sin duda el análisis para “podar” y dejar bien limpio el árbol de posibles operaciones tiene un gran mérito y es muy didáctico a los profanos (ley del buen programador: no basta con que el programa funcione, tiene que funcionar de forma óptima).

    Pero si cualquiera de nosotros nos pusiésemos a resolver uno de esos problemas del cifras (con nuestra materia gris); nuestra forma de abordarlo sería completamente distinta. Por ejemplo, yo cuando veía el programa solía empezar por buscar divisores enteros del resultado entre los números disponibles (y en caso de no haberlos, ver cuan cerca me quedaba). Algo que a mi entender simplificaba muchísimo el problema. Cuando leí tus artículos me quedó el gusanillo de no ser capaz de plasmar sobre código muchas de esas “estrategias de ataque” del problema que me salían de forma casi instintiva (y no quiero ni pensar en las que conocen verdaderos cracs en lo de operar de coco). Por algo será que terminé en sistemas, peleado con las abstracciones a código. XD

    Ahora reviviendo el tema has vuelto a lograr que me pique y por ello te odio un poquito más (pero de buen rollo) :-P

    Saludos!

    PD: Isanagi, si tuviera que darte un consejo, te diría que le inculcases el don (a veces malsano) de la curiosidad. Todos los que hemos terminando “trasteando cachivaches” empezamos sin darnos cuenta de pequeños. Cuando nuestros colegas jugaban con los juguetes de reyes y nosotros LOS DESMONTÁBAMOS para ver como funcionaban, aunque luego no pudiésemos montarlos de nuevo. Esa clase de curiosidad te hace ser mejor ingeniero, querer saber no sólo el “como” sino también “el porqué” de las máquinas y construcciones que nos rodean. Eso y aprender a ser metódico (solucionar problemas complejos por división o por eliminación de posibilidades) son para mi las dos herramientas básicas.

    PD2: Yo sí recuerdo haber visto en la tele algún (escaso) ejemplo de concursantes incluyendo operaciones con fracciones en sus respuestas (y dejando ojipláticos al personal en el proceso)

  9. Gravatar Macluskey | 31/01/2017 at 10:54 | Permalink

    Gracias, Jefe Ryback, por los (inmerecidos) elogios. Sí estoy un poco zumbado, es cierto, pero a estas alturas no pienso hacer nada para evitarlo… ¡y los manicomios salen carísimos! ;)

    En su día hubo la discusión de cuál sería la mejor estrategia para resolver el problema de cifras (el de letras no tiene mayor problema que tener un diccionario de palabras válidas).

    Hay dos estrategias posibles, creo yo.

    Una: dado un problema concreto, ver cómo puede resolverse de la mejor forma posible. Es lo que hacen los concursantes, claro está; tienen seis números y un objetivo y allá se las compongan. Y estrategias como la que citas (buscar divisores del objetivo es lo primero que hacemos casi todos) es lo que uno puede hacer ante ese problema concreto. Ya Antonio Villena en su día nos dijo que la solución obvia pasa por hacer un backtracking, y que además se puede optimizar, por ejemplo, teniendo en cuenta si hay números duplicados para no repetir operaciones que sabes que son la misma, etc.

    Dos: dar una solución que sirva para TODOS los problemas posibles, es decir, que un único programa con una única estrategia resuelva todos y cada uno de los treinta millones y pico de posibles problemas. Ésa es la que a mí, informático del Achelense, me gusta y me parece más correcta.

    Claro que también se puede programar esta segunda opción a base de ir probando trucos o estrategias traídas de la alternativa uno: Primero vemos si hay duplicados, luego si el objetivo es divisible por algún argumento, luego si lo es por la suma de dos, de tres, luego tal y luego cual… Se puede, claro. Pero ésa no es una solución nada efectiva, por una razón: cuando todas las estrategias que se nos ocurran fallan, si queremos agotar todas las posibilidades, entonces ¡sólo queda la fuerza bruta!

    Y digo yo: si de todos modos hay que programar el ataque por fuerza bruta cuando todos los IF’s fallan, cuando ninguna estrategia “humana” conocida funciona… pues ¡limitémonos a programar el ataque por fuerza bruta, y yastá! Se ahorra una barbaridad de tiempo y esfuerzo al hacerlo así.

    Eso sí, hacerlo a lo bruto-bruto es terriblemente ineficiente, como ya vimos en los artículos de hace cinco años, y entonces es cuando entra el divertido proceso de optimización que permite que probando sólo 600.000 fórmulas se pueda determinar la solución (si tiene) de cualquier problema.

    Por ejemplo: Si tuviéramos que enviar una sonda a Marte, podríamos programar una solución que llevase la sonda exclusivamente hasta Marte, teniendo en cuenta la posición relativa de ambos planetas, el momento del lanzamiento, etc. O bien podíamos programar una solución que fuera capaz de llevar una sonde desde cualquier planeta hasta cualquier otro y en cualquier momento temporal. En esta segunda solución los parámetros de entrada serían, más o menos: desde dónde sale la sonda, a dónde tiene que ir, y cuándo se produce la salida. Y valdría no sólo para ir a Marte, sino a Venus, a Neptuno o a donde fuera. Costaría más realizarlo que en el primer caso, pero estaría hecho para siempre.

    Esta forma de pensar, es decir, buscar la solución para resolver un tipo de problemas, no un problema concreto, es lo que, desde mi punto de vista, distingue a un buen informático de uno mejor todavía.

    Un saludo

  10. Gravatar Jefe Ryback | 31/01/2017 at 02:15 | Permalink

    Entiendo tu punto de vista sin duda, por eso te dije que tu opción no sólo era válida si no obvia; porque sin duda alguna te lleva a la solución y con un nivel de optimización (respecto la pura fuerza bruta sin análisis alguno) muy elevado.

    Haría falta hacer un estudio más a fondo de ver cual sería la estrategia que promediaría un mejor rendimiento y cuanto puedes llegar a ganar (en reducción de tiempo) si primero se aplican estrategias “inteligentes” antes de el ataque por fuerza bruta. Así como ver qué estrategias dan una gran reducción de tiempo promedio y cuales no aportan gran cosa

    Siguiendo tu símil de la sonda, imagínate que el día de mañana cambiasen el concurso añadiendo más operadores , cambiando los posibles y/o ampliando el rango de posibles resultados a valores de 4 cifras. Tu programa sigue sirviendo (modificando 4 parámetros) pero… ¿El crecimiento del árbol de posibilidades lo haría llegar a un punto de poca eficiencia? Al fin y al cabo el ordenamiento por burbuja es una “maravilla” por sencillez para no tenerte que romper el coco y reduciendo factores de error en el código… Hasta que te enchufan una lista de 100.000 elementos y el usuario se acuerda de los ancestros del programador de turno por lo mucho que tiene que esperar. XD

    Saludos

  11. Gravatar Isangi | 31/01/2017 at 03:45 | Permalink

    Hola,

    Macluskey, buenas ideas, lo de encontrarle problemas reales o plantearle basicos de informatica, ya lo tenia en mente, pero ahroa aún está en fase temprana.

    Ryback: Despertar curiosidad, uff, que dificil se me hace eso, por algo “nos” llaman Frikys, porque estamos interesados en cosas raras. Mi mujer es muy Friky, pero de otro estilo(dibujos animados, manga, twitter, juegos,…) pero me cuesta mucho conseguir que se interese por temas, por ejemplo, cientificos. (joder lo que disfruto leyendo el tamiz, pese a no saber casi nada de fisica ni quimica y menos de cuantica) Y para ella(y medio mundo) es un tostón… Y la edad(34) no creo que ayude, aunque no es el mayor de los problemas.

    quizá Parezco pesimista con estas respuestas, ni de lejos, solo que lo que uno ya tiene solventado/claro no lo pregunta… jejeje

    Respecto a la programación de la solución de cifras y letras, yo también me sorprendí al ver que lo solventabas por fuerza bruta, esperaba algo del estilo de Backtracking como comentas(aunque no he vuelto a programar nada de backtracking desde que dejé la uni….).

    aunque por lo que se de Backtracking(poco o nada), al final sería hacer por programación lo que tu ya hiciste mediante formulas, ir cortando todas aquellas ramas que no parecen(en tu caso “que estoy seguro”) llevar a buen termino. Estoy seguro que con backtracking el tiempo de programación hubiera aumentado, pero el tiempo(ciclos) de proceso habría disminuido enormemente para el 95% de los casos y más lento que la fuerza bruta “tuya” en el 5% restante(como siempre % inventados jejeje).

  12. Gravatar Oscar | 02/02/2017 at 09:11 | Permalink

    Donde esta Pedro? Entiendo que le ha tenido que ocurrir algo si no pública nada en años…

    Hecho mucho de menos sus publicaciones…

  13. Gravatar Macluskey | 04/02/2017 at 03:25 | Permalink

    Oscar:

    Pedro, por lo que sé, está perfectamente de salud. Cuando lo decida volverá a publicar. O eso esperamos todos… ;)

  14. Gravatar Jefe Ryback | 06/02/2017 at 11:53 | Permalink

    El día que vuelva a publicar, se le cae la web por exceso de tráfico, eso seguro. :-)

  15. Gravatar Oldman | 04/03/2017 at 08:29 | Permalink

    Mac…perdona que te involucre en esto. N’a qver con vuestras series aun vivas pero puede ser de interés para bastantes/muchos. Mi propuesta: Organizar y convocar un encuentro físico, y sin fórmulas, de todos los que podamos asistir entre los que hemos sido seguidores-partícipes de “El Tamiz” (incluido Pedro, que obviamente no podría faltar). Lugar: en una cervecería de Madrid (por ser donde vive el Jefe de los alienígenas). Tema: libremente afectivo, pero sin llorar demasiado. Objetivo: Nada más que…pues eso…Forma: a través de una convocatoria del ilustre intermediario Macluskey (previo acuerdo del plan con el susodicho), por ej., en los “últimos comentarios del Estado de cosas” pidiendo intención de asistencia y a repetir semanalmente durante dos meses para poder concretar el encuentro entre mayo y junio (y si no puede ser ahora pues en septiembre…pero empezando ya). Por favor, antes de decir “ce n’est pas posible” tómate el tiempo hasta después de que el proponente cumpla los 81 dentro de quince días…y después hablamos por email si quiers. Gracias y un saludo.

  16. Gravatar Macluskey | 22/03/2017 at 10:37 | Permalink

    Ah, ya veo… se me había pasado el comentario, Oldman.

    Te contesto por email…

  17. Gravatar Juan Carlos | 22/03/2017 at 05:02 | Permalink

    Sé que es mucho pedir pero… Puede ser la reunión acá en cualquier lugar de la costa este de Estados Unidos?

    :)

Escribe un comentario

Tu dirección de correo no es mostrada. Los campos requeridos están marcados *

Al escribir un comentario aquí nos otorgas el permiso irrevocable de reproducir tus palabras y tu nombre/sitio web como atribución.