Rust で整数を漢数字に変換したいよー
こんな感じで実装できる。真面目にやればもうちょいちゃんと書けるけどこんな感じで。。
use std::cmp::min;
const NUMS: [&str; 10] = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
const SUBS: [&str; 4] = ["", "十", "百", "千"];
const PARTS: [&str; 18] = [
"",
"万",
"億",
"兆",
"京",
"垓",
"𥝱",
"穣",
"溝",
"澗",
"正",
"載",
"極",
"恒河沙",
"阿僧祇",
"那由他",
"不可思議",
"無量大数",
];
fn int2kanji(i: i64) -> String {
let s = i.to_string();
let chars = s.bytes();
let p = chars.into_iter().rev().enumerate().collect::<Vec<_>>();
let mut buf: Vec<&'static str> = Vec::new();
for (i, b) in p.clone() {
let c = (b - 48) as usize; // 48 is '0'
if i % 4 == 0
&& i > 0
&& (i..min(i + 4, s.len()))
.map(|i| {
let (_, c) = p.get(i).unwrap();
*c
})
.any(|n| n != 48)
{
buf.push(PARTS[i / 4]);
}
if c != 0 {
// その桁が 0 のときは区切りを追加しない
buf.push(SUBS[i % 4]);
}
if !(i % 4 != 0 && c == 1) {
// 十百千を表示したときで、一のときは追加しない。
buf.push(NUMS[c]); // 48 is '0'
}
}
buf.reverse();
buf.join("")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_int2kanji() {
assert_eq!(int2kanji(1), "一");
assert_eq!(int2kanji(9), "九");
assert_eq!(int2kanji(10), "十");
assert_eq!(int2kanji(11), "十一");
assert_eq!(int2kanji(21), "二十一");
assert_eq!(int2kanji(99), "九十九");
assert_eq!(int2kanji(100), "百");
assert_eq!(int2kanji(999), "九百九十九");
assert_eq!(int2kanji(1000), "千");
assert_eq!(int2kanji(9999), "九千九百九十九");
assert_eq!(int2kanji(10000), "一万");
assert_eq!(int2kanji(10020), "一万二十");
assert_eq!(int2kanji(1_000_020), "百万二十");
assert_eq!(int2kanji(100_000_020), "一億二十");
assert_eq!(int2kanji(1_0000_4423), "一億四千四百二十三");
assert_eq!(int2kanji(1_8000_4423), "一億八千万四千四百二十三");
}
}