Skip to content

Instantly share code, notes, and snippets.

@bluebear94
Last active August 29, 2015 13:57
Show Gist options
  • Save bluebear94/9539418 to your computer and use it in GitHub Desktop.
Save bluebear94/9539418 to your computer and use it in GitHub Desktop.
import java.util._
import java.io._
object Mystery {
// It's a mystery.
val LUT: Array[String] = Array("\u3042", "\u3044", "\u3046", "\u3048", "\u304a",
"\u304b", "\u304d", "\u304f", "\u3051", "\u3053",
"\u3055", "\u3057", "\u3059", "\u305b", "\u305d",
"\u305f", "\u3061", "\u3064", "\u3066", "\u3068",
"\u306a", "\u306b", "\u306c", "\u306d", "\u306e",
"\u306f", "\u3072", "\u3075", "\u3078", "\u307b",
"\u307e", "\u307f", "\u3080", "\u3081", "\u3082",
"\u3084", "\u3090", "\u3086", "\u3044\u3047", "\u3088",
"\u3083", "\u3090", "\u3085", "\u3047", "\u3087",
"\u3089", "\u308a", "\u308b", "\u308c", "\u308d")
def lutShift(i: Int): String = LUT(i).map((_: Char) + off).foldLeft("")(_ + _.toChar)
val n = '\u3093'
val VOWELS = "aeioy"
val VOWELS_U = "äëïöÿ"
var off: Char = 0
val UCC: Array[Int] = Array(2,1,1,1,2,0,2,2,2,2)
val KATAKANA_OFFSET: Char = 0x60
def iv(c: Char) = c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'y'
def ic(c: Char) = !iv(c) || c.isWhitespace
def ivd(c: Char) = "äëïöÿ".indexOf(c) != -1
def goe(s: String, i: Int, c: Char): Char = if (i >= s.length || i < 0) c else s.charAt(i)
def v(i: Int, o: Int) = if (i == 2) lutShift(o+1)+(if (off == 0) LUT(1) else "\u30fc") else lutShift(o+Array(0,3,1,4,1).apply(i))
def t(c: Char): (Int, Int) = {
val x = "...cg.s..td.n..fvpm..,,,...rl.".indexOf(c)
(x / 3, x % 3)
}
def insert(s: String, t: String, i: Int) = s.substring(0, i) + t + s.substring(i)
def d(i: Int): String = i match {
case 0 => ""
case 1 => "\u3099"
case 2 => "\u309a"
}
def d(i: Int, t: Int, c: String): String = if (i + UCC(t) > 2) insert(c, d(i),1) else c.map(a => {if ((a - 0x3040) % 0x60 >= 11) i.toChar + a else a}).foldLeft("")(_ + _.toChar)
def mystery(ss: String): String = {
val s = ss.toLowerCase
var out = ""
var i = 0
off = 0
val l = s.length
while (i < l) {
var c = s.charAt(i)
var n = goe(s, i + 1, ' ')
if (c == '.') out += "。"
else if (c == ':') out += ":"
else if (c == ';') out += ";"
else if (c == '«') out += "「"
else if (c == '»') out += "」"
else if (c == '*') off = KATAKANA_OFFSET
else if (c == '{' && n == '{') {
val j = ss.indexOf("}}", i)
if (j == -1) throw new RuntimeException("Could not parse syntax")
out += ss.substring(i + 2, j)
i = j + 1
}
else if (!c.isLower && !c.isWhitespace && c != '\'') out += c
else if (iv(c)) {
if (c == 'i' && !n.isLower) c = 'y'
out += v(VOWELS.indexOf(c), 0)
}
else if (ivd(c)) out += v(VOWELS_U.indexOf(c), 0)
else if (c.isWhitespace) {
off = 0
out += (if (c == ' ') '\u3000' else c) // CJK space
}
else if (c != '\'') {
var p = goe(s, i + 2, ' ')
val q = goe(s, i + 3, ' ')
if (n == 'i' && iv(p)) {
if (c == 'r' || c == 'l') out += v(VOWELS.indexOf(p), 35)
if (c == 'l') out += "\u3099"
val u = t(c)
if (c != 'r' && c != 'l') {
val b = v(VOWELS.indexOf(p), 40)
out += d(u._2, u._1, lutShift(5 * u._1 + 1)) + b
}
i += 2
}
else if (c == n && p == 'i' && iv(q)) {
val u = t(c)
val w = (u._1, u._2 + 1)
val b = v(VOWELS.indexOf(q), 40)
if (c == 'l') out += v(VOWELS.indexOf(q), 35) + "\u309a"
else out += d(w._2, w._1, b)
i += 3
}
else if (iv(n) || (iv(p) && c == n)) {
if (c == 'h') {
c = 'f'
out += ('っ' + off).toChar
}
if (n == 'i' && !p.isLower) n = 'y'
var u = t(c)
if (c == n) {
u = (u._1, u._2 + 1)
out += d(u._2, u._1, v(VOWELS.indexOf(p), 5 * u._1))
i += 1
}
else out += d(u._2, u._1, v(VOWELS.indexOf(n), 5 * u._1))
i += 1
}
else if ((c == 'n' && n != 'p' || c == 'm' && n == 'p') && !ic(goe(s, i - 1, ' '))) out += (n + off).toChar
else {
if (c == 'd' && !n.isLower) c = 't'
var u = t(c)
if (c == n) {
u = (u._1, u._2 + 1)
out += d(u._2, u._1, lutShift(5 * u._1 + 2))
i += 1
}
else out += d(u._2, u._1, lutShift(5 * u._1 + 2))
}
}
i += 1
}
out
}
def mystConfg(s: String) = {
if (s.startsWith("#") || s == "") s
else {
val i = s.indexOf("=")
if (i == -1) throw new RuntimeException("Not a comment or a key-value pair")
s.substring(0, i + 1) + mystery(s.substring(i + 1))
}
}
def main(args: Array[String]) = {
val action = if (args.length == 0) "stdin" else args(0)
if (action == "stdin") {
val c = new Scanner(System.in)
var s = "a"
while (s != "") {
s = c.nextLine
if (s != "") println(mystery(s))
}
}
else {
val f = if (action == "text") mystery(_) else if (action == "config") mystConfg(_) else throw new RuntimeException(s"Unknown task $action")
val c = new Scanner(new File(args(1)))
val d = new PrintStream(new File(args(2)))
while (c.hasNextLine)
d.println(f(c.nextLine))
}
}
}
@bluebear94
Copy link
Author

This doesn't work with the new orthography. At this moment I have no plans to update this tool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment