I happen to have this program on hand since it’s a common problem on “coding challenge” websites. You have to decompose the number into groups of 3 digits each and then call the function for serializing the number into text recursively. Here’s the full solution:
use std::iter::successors;
const ONES: [&str; 20] = [
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen",
];
const TENS: [&str; 10] = [
"zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty",
"seventy", "eighty", "ninety",
];
const ORDERS: [&str; 7] = [
"zero",
"thousand",
"million",
"billion",
"trillion",
"quadrillion",
"quintillion", // enough for u64::MAX
];
pub fn encode(num: u64) -> String {
match num {
0..=19 => ONES[num as usize].to_string(),
20..=99 => {
let upper = (num / 10) as usize;
match num % 10 {
0 => TENS[upper].to_string(),
lower => format!("{}-{}", TENS[upper], encode(lower)),
}
}
100..=999 => format_num(num, 100, "hundred"),
_ => {
let (div, order) =
successors(Some(1u64), |v| v.checked_mul(1000))
.zip(ORDERS.iter())
.find(|&(e, _)| e > num / 1000)
.unwrap();
format_num(num, div, order)
}
}
}
fn format_num(num: u64, div: u64, order: &str) -> String {
match (num / div, num % div) {
(upper, 0) => format!("{} {}", encode(upper), order),
(upper, lower) => {
format!("{} {} {}", encode(upper), order, encode(lower))
}
}
}
0
solved How to transform a Rust number into English words, like 1 -> “one”?