Skip to content

Instantly share code, notes, and snippets.

@axelchalon
Last active June 7, 2017 12:07
Show Gist options
  • Save axelchalon/c4c83c6114863e6ace7f6c72c8412293 to your computer and use it in GitHub Desktop.
Save axelchalon/c4c83c6114863e6ace7f6c72c8412293 to your computer and use it in GitHub Desktop.
Spell out a number
use std::io::prelude::*;
use std::collections::LinkedList;
const COMMA_SEPARATOR: bool = true;
fn spell(number: u64) -> String {
#![allow(overflowing_literals)]
match number {
// 0-9
0 => String::from("zero"),
1 => String::from("one"),
2 => String::from("two"),
3 => String::from("three"),
4 => String::from("four"),
5 => String::from("five"),
6 => String::from("six"),
7 => String::from("seven"),
8 => String::from("eight"),
9 => String::from("nine"),
// 10-99
10 => String::from("ten"),
11 => String::from("eleven"),
12 => String::from("twelve"),
13 => String::from("thirteen"),
14 => String::from("fourteen"),
15 => String::from("fifteen"),
16 => String::from("sixteen"),
17 => String::from("seventeen"),
18 => String::from("eighteen"),
19 => String::from("nineteen"),
20 => String::from("twenty"),
30 => String::from("thirty"),
40 => String::from("forty"),
50 => String::from("fifty"),
60 => String::from("sixty"),
70 => String::from("seventy"),
80 => String::from("eighty"),
90 => String::from("ninety"),
20...99 => {
let first_digit = number/10;
let second_digit = number%10;
format!("{}-{}",spell(first_digit * 10),spell(second_digit))
},
// 100-999
100...999 => {
let first_digit = number/100;
let last_two_digits = number%100;
if last_two_digits == 0 {
format!("{} hundred",spell(first_digit))
} else {
format!("{} hundred {}",spell(first_digit),spell(last_two_digits))
}
},
// 1000-999_999_999_999_999_999_999
1000...999_999_999_999_999_999_999 => {
// Split number in groups of 3 from right to left
// 1_355_823 => [823,355,1]
// and spell out each group
// ["eight hundred twenty-three", "three hundred fifty-five", "one"]
let mut spelled_groups_rtl: LinkedList<String> = LinkedList::new();
{
let mut rest = number;
while rest > 0 {
let new_rest = rest/1000;
let rightmost_group = rest%1000;
spelled_groups_rtl.push_back(
if rightmost_group == 0 {
String::from("")
} else {
spell(rightmost_group)
}
);
rest = new_rest;
}
}
// Zip to add suffixes
// ["eight hundred twenty-three", "three hundred fifty-five thousand", "one million"]
let mut spelled_parts_rtl: LinkedList<String> = LinkedList::new();
{
let suffixes = ["", " thousand", " million", " billion", " trillion", " quadrillion", " quintillion"];
for (spelled_group, suffix) in spelled_groups_rtl.iter().zip(suffixes.iter()) {
if spelled_group != "" {
spelled_parts_rtl.push_back(format!("{}{}",spelled_group,suffix));
}
}
}
// Reverse and concatenate
// "one million three hundred fifty-five thousand eight hundred twenty-three"
let mut result = String::new();
for spelled_part in spelled_parts_rtl.iter() {
if result == "" || !COMMA_SEPARATOR {
result = format!("{} {}",spelled_part,result);
} else {
result = format!("{}, {}",spelled_part,result);
}
}
String::from(result.trim())
},
_ => String::from("No idea")
}
}
fn main() {
loop {
print!("Please enter a number (or type \"exit\" to quit): ");
std::io::stdout().flush().expect("Couldn't flush");
let mut input_str = String::new();
std::io::stdin().read_line(&mut input_str).expect("Couldn't read from stdin");
if input_str.trim() == "exit" {
println!("See you soon!");
return;
}
let input_int_option: Option<u64> = input_str.trim().parse().ok();
if input_int_option.is_none() {
println!("This doesn't seem to be a number.");
println!("");
continue;
}
let input_int: u64 = input_int_option.unwrap();
println!("Spelled out: {}",spell(input_int));
println!("");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment