Last active
August 29, 2015 13:57
-
-
Save bluebear94/9539418 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This doesn't work with the new orthography. At this moment I have no plans to update this tool.