72 lines
2.2 KiB
Plaintext
72 lines
2.2 KiB
Plaintext
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: Write>(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();
|
|
}
|
|
}
|