use std::io::{self, Write, stdout}; const SMALL: &[&str] = &[ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", ]; const TENS: &[&str] = &[ "PANIC", "PANIC", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety", ]; const MAGNITUDE: &[&str] = &[ "PANIC", "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", ]; fn wordify(w: &mut W, mut number: i64) -> Result<(), io::Error> { if number == 0 { return write!(w, "zero"); } if number < 0 { write!(w, "negative ")?; number = -number; } while number != 0 { if number < 20 { write!(w, "{}", SMALL[number as usize])?; break; } else if number < 100 { write!(w, "{}", TENS[number as usize / 10])?; number %= 10; if number != 0 { write!(w, "-")?; } } else if number < 1_000 { write!(w, "{} hundred", SMALL[number as usize / 100])?; number %= 100; if number != 0 { write!(w, " and ")?; } } else { let mut top = number; let mut magnitude = 0i64; let mut magnitude_pow = 1i64; while top >= 1_000 { top /= 1_000; magnitude += 1; magnitude_pow *= 1_000; } wordify(w, top)?; number %= magnitude_pow; if number == 0 { write!(w, " {}", MAGNITUDE[magnitude as usize])?; } else if number > 100 { write!(w, " {}, ", MAGNITUDE[magnitude as usize])?; } else { write!(w, " {} and ", MAGNITUDE[magnitude as usize])?; } } } Ok(()) } fn main() { let stdout = stdout(); let mut stdout = stdout.lock(); for &n in &[12, 1048576, 9_000_000_000_000_000_000, -2, 0, 5_000_000_000_000_000_001, -555_555_555_555] { wordify(&mut stdout, n).unwrap(); write!(&mut stdout, "\n").unwrap(); } }