「一反田えー」、つまり「1反田A」から始めて、「二反田びー(2反田B)」、「三反田しー(3反田C)」と続けていく(Zまで来たらAに戻って循環)と、1000では米澤穂信の推理小説である「〈古典部〉シリーズ」のメインヒロイン、「千反田える」になるそうです。
「一反田えー、二反田びー、……二十六反田ぜっと、二十七反田えー、……」と定義したとき、「千反田」は「える」になる。 というツイートが朝から回ってくるので本当にそうなるかプログラムを走らせた結果 http://twitpic.com/b8q90b
https://twitter.com/_Kabix/status/263229881435971584
「私、気になります!」という事で、Groovyで書いてみました。方針は以下のようにしました。
- 漢数字のスタートは1、平仮名表記のアルファベットのスタートは0のため、
eachWithIndex
を用いてそれぞれの配列のインデックスにしました - より汎用的に、千以上の数字にも対応しました
- 位の表現変換は、「一十百千」までと、「万億兆…」の2段階に分けて変換しました
- 変換する値の桁数の検出は、値を文字列に変換してから文字数を得る事で行いました。
def alphabetList = ["えー", "びー", "しー", "でぃー", "いー", "えふ", "じー", "えいち", "あい", "じぇい", "けー", "える", "えむ", "えぬ", "おー", "ぴー", "きゅー", "あーる", "えす", "てぃー", "ゆー", "ぶい", "だぶりゅー", "えっくす", "わい", "ぜっと"]
def range = 1..1000
range.eachWithIndex {num, i->
println "${arabicNumToKanjiNum(num)}反田${alphabetList[i%alphabetList.size()]}"
}
// アラビア数字を漢数字に変換します
def arabicNumToKanjiNum(long num){
def kanjiNumUnit = ["", "万", "億", "兆", "京"]
// 4桁ごとのブロックの数
int blockIndex = num.toString().size() / 4
def kanji = ""
while (blockIndex >= 0) {
// ブロックの値のみを残す
int value = num / (10000 ** blockIndex)
int blockNum = value % 10000
// ブロックの値が1以上のとき
if (blockNum >= 1) {
kanji = "${kanji}${arabicNumToKanjiNumSub(blockNum)}${kanjiNumUnit[blockIndex]}"
}
blockIndex--
}
kanji
}
// 一万未満のアラビア数字を漢数字に変換します
def arabicNumToKanjiNumSub(int num){
def kanjiNum = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九" ]
def kanjiNumSubUnit = ["", "十", "百", "千"]
// 数字の桁数
int digitIndex = num.toString().size() - 1
def kanji = ""
while (digitIndex >= 0) {
// 指定した桁の値のみを残す
int value = num / (10 ** digitIndex)
int numIndex = value % 10
// 桁の数字が2以上(「一百」などを避ける)
// または1桁目の数字(1桁目は「一」を表示)の場合
if (numIndex >= 2 || digitIndex == 0) { //
// 漢数字を追加
kanji = "${kanji}${kanjiNum[numIndex]}"
}
// 桁の数字が1以上のとき
if(numIndex >= 1) {
// 百などを表示
kanji = "${kanji}${kanjiNumSubUnit[digitIndex]}"
}
digitIndex--
}
kanji
}
Groovyコードはファイルに保存してからgroovy
コマンドで実行しても良いですが、GroovyConsoleに貼りつける事で簡単に実行できます。実行結果は「千反田える」になりました!