Encuentra la diferencia – versión Kanji – en Scala

Y ya con este código dejo el tema por la paz. Lo pongo para que quede en el registro:

object Uniques {
  def main(a: Array[String]) {
    if (a.length != 1) {
      println("Need an argument to analyze")
      sys.exit(1)
    }
    else {
      findUniques(a(0)) match {
        case l if (l.isEmpty) => println("All characters are the same")
        case l => l foreach println
      }
    }
  }

  def findUniques(seq: String) =  seq filter {c => seq.count(_ == c) == 1} map {c => "Unique instance found: " + c + " in position " + (seq.indexOf(c) + 1)}
}

Y probando el caso en cuestión:

mmedina@yggdrasil-m:~/Programming/Scala/Tests$ scala Uniques "麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈塵麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈 麈麈麈麈麈麈麈麈麈"
Unique instance found: 塵 in position 66

Hacerlo para que funcione con otros tipos de datos sin cambiar nada de código no es muy complicado.

Encuentra la diferencia – versión Kanji – en Haskell

Lo prometido es deuda. Siguiendo con el escrito anterior, aquí está el código que resuelve el problema, pero ahora en Haskell:

import qualified Data.ByteString as B
import qualified Data.ByteString.UTF8 as U
import System.Environment(getArgs)
import Data.List
import Data.Maybe

main = do
    putStrLn "Write the sequence you want to analyze:"
    B.getLine >>=  processArguments

processArguments :: B.ByteString ->  IO ()
processArguments xs = findUniques $ U.toString xs

findUniques = printUniques . findUniques'

findUniques' :: (Eq a, Show a) => [a] ->  [(a,Int)]
findUniques' xs = let uniques = filter (\i ->  countInstances i xs == 1) $ nub xs
                  in [(x,y) | x <- uniques, y <- mapMaybe (\i ->  i `elemIndex` xs) [x]]

printUniques :: (Eq a, Show a) =>  [(a,Int)] ->  IO ()
printUniques [] = putStrLn "All instances are the same"
printUniques us = mapM_ putStrLn $ map (\c →  ((("Unique instance: " ++ ) $ show $ fst c) ++ ) $ ((" in position " ++ ) $ show $ (+1) $ snd c)) us

countInstances :: (Eq a, Show a) =>  a ->  [a] ->  Int
countInstances _ [] = 0
countInstances c (x:xs)
    | c == x = 1 + countInstances c xs
    | otherwise = countInstances c xs

 

Es un hecho que puedo usar un where en la definición de printUniques, pero bueno, el caso es que funciona:

mmedina@yggdrasil-m:~/Programming/Haskell/FindDifference$ ./fdc
Write the sequence you want to analyze:
麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈塵麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈麈
Unique instance: '\22645' in position 66

Todo muy bonito, sí. Pero entonces: ¿para qué tanto código en Haskell? Explico:

Continue reading “Encuentra la diferencia – versión Kanji – en Haskell”

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.

Año fiscal nuevo, Saint Seiya nuevo

Actualización:

Lo dicho: ya no están los episodios en los links que tenía antes, pero con la fiebre que está causando la serie por allá, más de alguno sabe dónde conseguirlos o verlos.

Actualización:

Fueron rápidos. Ya está el episodio en Youtube, dividido en 2 partes. Véanlo antes de que lo quiten. Gracias a @Aries_Tj por la información. Obviamente están en japonés.

[youtube]http://www.youtube.com/watch?v=-nvDUzNgL94[/youtube]

[youtube]http://www.youtube.com/watch?v=SWur9gr3JTc[/youtube]

Ha comenzado un nuevo año fiscal en Japón: nuevo ciclo escolar, los recién egresados entran a las compañías a trabajar, y la ronda de estrenos de animación de primavera también hace su aparición.

Algunos lo consideraban leyenda urbana, otros ya habían visto el anuncio oficial… Como sea, el caso es que hay nueva serie de Saint Seiya. Y aunque no me emociona mucho el horario en el que la están transmitiendo (ya les comentaré el porqué), no puedo negar que sentí un poco de nostalgia al ver de nuevo en TV a Seiya y poder gritarle que no sirve para nada y que debía morir de unas 24 maneras diferentes 😛

¿Por qué no me emociona el horario? Bueno: consideremos que es los domingos a las 6:30 am. Olvídense de que es pecado mortal levantarse ese día a esa hora, ya que para eso existe el torne: los domingos por la mañana se caracterizan por ser la barra programación infantil; por aquí pasan programas como Pretty Cure, las mil y una versiones de Kamen Rider, y en fin, caricaturas para un público de menor edad de la que podríamos esperar para una serie como Saint Seiya. De verdad que me gustaría mucho estar equivocado y que resulte ser una serie atractiva… Creo que sólo el tiempo me podrá responder.

[youtube]http://www.youtube.com/watch?v=IKNtnF2s61s[/youtube]

En fin. El caso es que la serie comienza con Saori y un bebé. Un malo malote llega, y Saori se dispone a proteger al bebé. El malote ataca y en ese momento cuando hace su aparición triunfal el personaje X, o sea Seiya, sip, el original, como saint (caballero) dorado, visitendo la cross (armadura) de sagitario. El malote, después de que ve su ataque reducido a nada, expresa: 「流石ゴールドセイント」, es decir, “como era de esperarse de un saint dorado”, confirmando así que Seiya es oficialmente el saint dorado de sagitario (por si a alguien todavía pudiera sorprenderle). Seiya hace su pose tradicional y lanza el ペガサス流星拳 o en español, el “meteoro pegaso”, mientras que el bebé en los brazos de Saori ve a su salvador de espaldas.

Unos 13 años después vemos a un chico (que adivinamos sin problemas que es aquel bebé) siendo entrenado por Shaina, sí, la misma de antes. Este chico, de nombre Kouga (光牙) es el nuevo candidato a la armadura de pegaso, pero nunca ha sentido el cosmo, no entiende por qué tiene que convertirse en saint, y detesta la idea de que alguien más decida el destino que él debe seguir. Shaina lo reprime mucho, diciéndole que si no puede despertar su cosmo, no podrá defender a Atena, a lo que Kouga responde que dónde está Atena y que lo lleve ante ella, de otra forma no puede creer nada.

Para no hacerles el cuento largo: Saori al parecer está siendo consumida por energía negativa. Llega un malo malote a llevársela argumentando que para poder conquistar el mundo necesitan de ella. Obviamente Saori reacciona enciendiendo su cosmo, momento en el que Kouga se da cuenta que Saori es Atena (por si no lo sabían :P); Saori se dispone a pelear, pero en eso llega Shaina y comienza la pelea del malo contra ella, la cual termina rápidamente con la victoria del malote. Kouga, a quien Saori justo acababa de regalarle un collar con una especie de diamante, dice que él protegerá a Atena, su cosmo se prende, y del collar sale una luz que resulta ser la armadura de pegaso. Kouga, al mismo tiempo, ve la visión de aquel sujeto en armadura dorada que peleó hace mucho tiempo (léase “Seiya”),  y Seiya le dice que lo que está sintiendo es el cosmo, y que lo tiene que hacer arder. Acto seguido, Kouga lanza el fantabuloso y trillado ペガサス流星拳 (meteoro pegaso) y … ahí termina el capítulo.

¿Qué les puedo decir? Sinceramente, el principio estuvo mejor de lo que esperaba, pero aún es imposible decir si la serie pinta bien o no. Lo que me sorprendió es que ahora todo está situado en el futuro, y Seiya (y quiero creer que los demás, Shiryu, Shun, Ikki y Hyoga) está posicionado dentro de los saint dorados, consolidando todo lo que hizo en el pasado. Veamos como se desenvuelve la historia.

Algunos detalles:

  • La voz de Saori, y la intérprete del opening, es 中川翔子(Nakagawa Shoko), mejor conocido como “Shokotan”, una embajadora del mundo otaku que brincó al mainstream hace ya varios años.
  • La canción del opening es una versión nueva de Pegasus Fantasy, titulada originalmente como “ペガサス幻想 ver. Ω” (Pegasus Fantasy, versión Omega). La letra es la misma.
  • La voz de Seiya es la del seiyuu original, es decir 古谷徹 (Furuya Tooru).
  • Seiya es muy chafa (opinión personal desde hace muuuuuchos años).

¿Cómo la ven? Yo opino que hay que darle una oportunidad. Insisto: no espero mucho de esta serie, pero ojalá me equivoque y resulte ser algo digno de ser recordado.

Por cierto, otra de las series que comienzan, y que vaya que hacía falta que algo así llegara, es Lupin III, a partir del 4 de abril. La serie se titula “Lupin III: una mujer llamada Mine Fujiko” (ルパン三世:峰不二子という女). Acá les dejo el video promocional:

[youtube]http://www.youtube.com/watch?v=Om_UdToxqqE[/youtube]