Encuentra la diferencia – versión Kanji

Hace unos días, me llegó un retweet con lo siguiente:

【間違い探し☆超超超超上級編】 麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈塵麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈 解けたらRT!

El punto es encontrar el kanji que es diferente, y al hacerlo, enviar el mensaje en un RT. Según el principio del mensaje, este problema es de nivel súper-súper-súper-súper avanzando.

“Buena forma de pasar el tiempo”, pensé, pero no para resolverlo “a mano”, sino creando un programa que lo hiciera por mí.

Viendo mis opciones, decidí programar el algoritmo en Python, tanto como práctica como para seguir dándome de topes por lo de las string unicode vs byte strings (quienes saben python entienden a lo que me refiero).

En sí, el algoritmo es sencillo, así que no tomó mucho tiempo:

# -*- coding: utf-8 -*-

import sys

def searchDifferentKanji(strseq):
    utf8Str = unicode(strseq,"utf-8")
    difstr = list(set(utf8Str))

    for c in difstr:
        if utf8Str.count(c) == 1:
            return c.encode("utf-8"), utf8Str.index(c) + 1

    return '',-1

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print "Error: Need a string to check"
        exit(1)
    else:
        difchar, pos = searchDifferentKanji(sys.argv[1])
        if pos != -1:
            print "Different char: " + unicode(difchar,"utf-8") + " in position " + str(pos)
        else:
            print "All characters are the same"

Lo que hago es simple: creo un set a partir de la cadena, haciendo con esto que todos los elementos repetidos se esfumen, y lo convierto a lista, la cual contiene exactamente un carácter por cada carácter diferente en la cadena original. Después recorro esa lista buscando en la cadena si el elemento actual aparece una sola vez; de ser así, es el carácter que estoy buscando, por lo que lo regreso, junto con la posición en la que está.

Existen problemas similares que contienen más de una diferencia, es decir: entre un mar de repeticiones del mismo carácter se encuentran varios diferentes. Para resolverlos, el algoritmo arriba expuesto puede ser sencillamente modificado para que no rompa el ciclo con el primer carácter diferente que encuentre, y agregue la tupla de (carácter,posición) a una lista, que sería el valor que la función “searchDifferentKanji” regresaría.

Como nota adicional, el kanji de ese problema es , que se lee 「しゅ」(shu), y conlleva el significado de “ciervo grande”. El kanji diferente es , con varias lecturas, entre ellas las más comúnes 「ちり」 (chiri), que significa “polvo”, “basura” y 「ごみ」(gomi), que también significa “basura”.

Sí: me queda de tarea hacerlo en Haskell.

11 thoughts on “Encuentra la diferencia – versión Kanji”

  1. Saludos.

    Vaya que es muy interesante como un Twitt puede ser divertido y con esa forma tan poco comun de encontrar la respuesta, cualquiera e pone a ver horas y horas la imagen y no encontrar nada. xD pero obviamente es un muy buen acertijo, la manera de verlo mediando la optica de la programacin, simlemente es fantastico.

    Como resolver un problema aparentemente dificil, programando un algoritmo que lo haga por ti. y en algunos minutos imagino que lo elaboro.

    Que tengas buen dia.

  2. Pff! Es más rápido encontrarlo haciendo bizcos (o antibizcos), como si fuera un estereograma (RDS).
    Está en el segundo renglón, por arriba de donde tú escribiste “enviar EL mensaje”.

  3. yo sigo jugando con haskell

    qs [] = []
    qs (x:xs) = (qs foo) ++ [x] ++ (qs bar)
    where foo = filter (=x) xs

    diferentes :: String -> (Char,Char)
    diferentes s = (head k, last k)
    where k = guess s

    diferentes “麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈 麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈塵麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈塵麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈”

    (‘\22645′,’\40584’) y ahí están tus dos kanjis diferentes. Pensandolo bien creo que es mucho más sencillo aprenserse el unicode de cada kanji que el dibujo jaja

  4. Hice un código en AS3 que compara el primer carácter con todos los demás. Si encuentra alguno diferente muestra una salida en la consola con el carácter y la posición.

    var LineaDeTexto: String = “mmmmmMmmmm”;

    function compara(txt1: String, txt2: String): Boolean
    {
    if (txt1 == txt2)
    {
    return true;
    }
    else
    {
    return false;
    }

    };

    function main(): void
    {
    for (var i: Number = 0; i == LineaDeTexto.length – 1; i++)
    {
    if (compara(LineaDeTexto.slice(0, 1), LineaDeTexto.slice(i, 1)))
    {
    trace(“Salió el caracter ” + LineaDeTexto.slice(i, 1) + ” en la posición ” + i);
    }
    else
    {
    trace(“Como las mujeres: Todas son iguales”);
    }

    };
    };

    Es con flash o flex.

    Saludos.

  5. Lo encontré en menos de 10 segundos. ¿Eso significa que soy inteligente para el juego, o que me quedaré ciego muy pronto?

  6. Solo lo vi y a la primera vi cual era el diferente, de hecho luego luego se nota es demasiado facil o.o

  7. Marco:
    ¿Y si el carácter diferente es el primero? (caso raro, pero lo debes checar en un programa): “Mmmmmmmmmmmmm”

  8. diego:
    ¿Estilo Quicksort? Jeje. Ya vi lo que hiciste. En pocas líneas está bien, pero no creo que haya necesidad de tanta recursividad. De todas formas, funciona 😀

  9. Manuel:

    Esta es la salida cuando el primer carácter es diferente:

    “Salió el carácter  “塵” en la posición 1″.

    El primero contra que se compara a sí mismo termina la función.

Leave a Reply

Your email address will not be published. Required fields are marked *