Four is the number of letters in the ...: Difference between revisions
Content added Content deleted
(C - use GLib) |
(Added Rust solution) |
||
Line 1,631: | Line 1,631: | ||
3 is the length of word 1000000 [the] |
3 is the length of word 1000000 [the] |
||
length of sentence= 7113621 |
length of sentence= 7113621 |
||
</pre> |
|||
=={{header|Rust}}== |
|||
{{trans|C}} |
|||
<lang rust>struct NumberNames { |
|||
cardinal: &'static str, |
|||
ordinal: &'static str |
|||
} |
|||
impl NumberNames { |
|||
fn get_name(&self, ordinal: bool) -> &'static str { |
|||
if ordinal { |
|||
return self.ordinal; |
|||
} |
|||
self.cardinal |
|||
} |
|||
} |
|||
const SMALL_NAMES: [NumberNames; 20] = [ |
|||
NumberNames { cardinal: "zero", ordinal: "zeroth" }, |
|||
NumberNames { cardinal: "one", ordinal: "first" }, |
|||
NumberNames { cardinal: "two", ordinal: "second" }, |
|||
NumberNames { cardinal: "three", ordinal: "third" }, |
|||
NumberNames { cardinal: "four", ordinal: "fourth" }, |
|||
NumberNames { cardinal: "five", ordinal: "fifth" }, |
|||
NumberNames { cardinal: "six", ordinal: "sixth" }, |
|||
NumberNames { cardinal: "seven", ordinal: "seventh" }, |
|||
NumberNames { cardinal: "eight", ordinal: "eighth" }, |
|||
NumberNames { cardinal: "nine", ordinal: "ninth" }, |
|||
NumberNames { cardinal: "ten", ordinal: "tenth" }, |
|||
NumberNames { cardinal: "eleven", ordinal: "eleventh" }, |
|||
NumberNames { cardinal: "twelve", ordinal: "twelfth" }, |
|||
NumberNames { cardinal: "thirteen", ordinal: "thirteenth" }, |
|||
NumberNames { cardinal: "fourteen", ordinal: "fourteenth" }, |
|||
NumberNames { cardinal: "fifteen", ordinal: "fifteenth" }, |
|||
NumberNames { cardinal: "sixteen", ordinal: "sixteenth" }, |
|||
NumberNames { cardinal: "seventeen", ordinal: "seventeenth" }, |
|||
NumberNames { cardinal: "eighteen", ordinal: "eighteenth" }, |
|||
NumberNames { cardinal: "nineteen", ordinal: "nineteenth" } |
|||
]; |
|||
const TENS: [NumberNames; 8] = [ |
|||
NumberNames { cardinal: "twenty", ordinal: "twentieth" }, |
|||
NumberNames { cardinal: "thirty", ordinal: "thirtieth" }, |
|||
NumberNames { cardinal: "forty", ordinal: "fortieth" }, |
|||
NumberNames { cardinal: "fifty", ordinal: "fiftieth" }, |
|||
NumberNames { cardinal: "sixty", ordinal: "sixtieth" }, |
|||
NumberNames { cardinal: "seventy", ordinal: "seventieth" }, |
|||
NumberNames { cardinal: "eighty", ordinal: "eightieth" }, |
|||
NumberNames { cardinal: "ninety", ordinal: "ninetieth" } |
|||
]; |
|||
struct NamedNumber { |
|||
cardinal: &'static str, |
|||
ordinal: &'static str, |
|||
number: usize |
|||
} |
|||
impl NamedNumber { |
|||
fn get_name(&self, ordinal: bool) -> &'static str { |
|||
if ordinal { |
|||
return self.ordinal; |
|||
} |
|||
self.cardinal |
|||
} |
|||
} |
|||
const N: usize = 7; |
|||
const NAMED_NUMBERS: [NamedNumber; N] = [ |
|||
NamedNumber { |
|||
cardinal: "hundred", |
|||
ordinal: "hundredth", |
|||
number: 100 |
|||
}, |
|||
NamedNumber { |
|||
cardinal: "thousand", |
|||
ordinal: "thousandth", |
|||
number: 1000 }, |
|||
NamedNumber { |
|||
cardinal: "million", |
|||
ordinal: "millionth", |
|||
number: 1000000 |
|||
}, |
|||
NamedNumber { |
|||
cardinal: "billion", |
|||
ordinal: "billionth", |
|||
number: 1000000000 }, |
|||
NamedNumber { |
|||
cardinal: "trillion", |
|||
ordinal: "trillionth", |
|||
number: 1000000000000 |
|||
}, |
|||
NamedNumber { |
|||
cardinal: "quadrillion", |
|||
ordinal: "quadrillionth", |
|||
number: 1000000000000000 |
|||
}, |
|||
NamedNumber { |
|||
cardinal: "quintillion", |
|||
ordinal: "quintillionth", |
|||
number: 1000000000000000000 |
|||
} |
|||
]; |
|||
fn big_name(n: usize) -> &'static NamedNumber { |
|||
for i in 1..N { |
|||
if n < NAMED_NUMBERS[i].number { |
|||
return &NAMED_NUMBERS[i - 1]; |
|||
} |
|||
} |
|||
&NAMED_NUMBERS[N - 1] |
|||
} |
|||
fn count_letters(s: &str) -> usize { |
|||
let mut count = 0; |
|||
for c in s.chars() { |
|||
if c.is_alphabetic() { |
|||
count += 1; |
|||
} |
|||
} |
|||
count |
|||
} |
|||
struct WordList { |
|||
words: Vec<(usize, usize)>, |
|||
string: String |
|||
} |
|||
impl WordList { |
|||
fn new() -> WordList { |
|||
WordList { words: Vec::new(), string: String::new() } |
|||
} |
|||
fn append(&mut self, s: &str) { |
|||
let offset = self.string.len(); |
|||
self.string.push_str(&s); |
|||
self.words.push((offset, offset + s.len())); |
|||
} |
|||
fn extend(&mut self, s: &str) { |
|||
let len = self.words.len(); |
|||
let mut w = &mut self.words[len - 1]; |
|||
w.1 += s.len(); |
|||
self.string.push_str(&s); |
|||
} |
|||
fn len(&self) -> usize { |
|||
self.words.len() |
|||
} |
|||
fn sentence_length(&self) -> usize { |
|||
let n = self.words.len(); |
|||
if n == 0 { |
|||
return 0; |
|||
} |
|||
self.string.len() + n - 1 |
|||
} |
|||
fn get_word(&self, index: usize) -> &str { |
|||
let w = &self.words[index]; |
|||
&self.string[w.0..w.1] |
|||
} |
|||
} |
|||
fn append_number_name(words: &mut WordList, n: usize, ordinal: bool) -> usize { |
|||
let mut count = 0; |
|||
if n < 20 { |
|||
words.append(SMALL_NAMES[n].get_name(ordinal)); |
|||
count += 1; |
|||
} else if n < 100 { |
|||
if n % 10 == 0 { |
|||
words.append(TENS[n/10 - 2].get_name(ordinal)); |
|||
} else { |
|||
words.append(TENS[n/10 - 2].get_name(false)); |
|||
words.extend("-"); |
|||
words.extend(SMALL_NAMES[n % 10].get_name(ordinal)); |
|||
} |
|||
count += 1; |
|||
} else { |
|||
let big = big_name(n); |
|||
count += append_number_name(words, n/big.number, false); |
|||
if n % big.number == 0 { |
|||
words.append(big.get_name(ordinal)); |
|||
count += 1; |
|||
} else { |
|||
words.append(big.get_name(false)); |
|||
count += 1; |
|||
count += append_number_name(words, n % big.number, ordinal); |
|||
} |
|||
} |
|||
count |
|||
} |
|||
fn sentence(count: usize) -> WordList { |
|||
let mut result = WordList::new(); |
|||
const WORDS: &'static [&'static str] = &[ |
|||
"Four", "is", "the", "number", "of", "letters", "in", "the", |
|||
"first", "word", "of", "this", "sentence,"]; |
|||
for s in WORDS { |
|||
result.append(s); |
|||
} |
|||
let mut n = result.len(); |
|||
let mut i = 1; |
|||
while count > n { |
|||
let count = count_letters(result.get_word(i)); |
|||
n += append_number_name(&mut result, count, false); |
|||
result.append("in"); |
|||
result.append("the"); |
|||
n += 2; |
|||
n += append_number_name(&mut result, i + 1, true); |
|||
result.extend(","); |
|||
i += 1; |
|||
} |
|||
result |
|||
} |
|||
fn main() { |
|||
let mut n = 201; |
|||
let s = sentence(n); |
|||
println!("Number of letters in first {} words in the sequence:", n); |
|||
for i in 0..n { |
|||
if i != 0 { |
|||
if i % 25 == 0 { |
|||
println!(); |
|||
} else { |
|||
print!(" "); |
|||
} |
|||
} |
|||
print!("{:2}", count_letters(s.get_word(i))); |
|||
} |
|||
println!(); |
|||
println!("Sentence length: {}", s.sentence_length()); |
|||
n = 1000; |
|||
while n <= 10000000 { |
|||
let s = sentence(n); |
|||
let word = s.get_word(n - 1); |
|||
print!("The {}th word is '{}' and has {} letters. ", n, word, |
|||
count_letters(word)); |
|||
println!("Sentence length: {}", s.sentence_length()); |
|||
n *= 10; |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
Number of letters in first 201 words in the sequence: |
|||
4 2 3 6 2 7 2 3 5 4 2 4 8 3 2 3 6 5 2 3 5 3 2 3 6 |
|||
3 2 3 5 5 2 3 5 3 2 3 7 5 2 3 6 4 2 3 5 4 2 3 5 3 |
|||
2 3 8 4 2 3 7 5 2 3 10 5 2 3 10 3 2 3 9 5 2 3 9 3 2 |
|||
3 11 4 2 3 10 3 2 3 10 5 2 3 9 4 2 3 11 5 2 3 12 3 2 3 |
|||
11 5 2 3 12 3 2 3 11 5 2 3 11 3 2 3 13 5 2 3 12 4 2 3 11 |
|||
4 2 3 9 3 2 3 11 5 2 3 12 4 2 3 11 5 2 3 12 3 2 3 11 5 |
|||
2 3 11 5 2 3 13 4 2 3 12 3 2 3 11 5 2 3 8 3 2 3 10 4 2 |
|||
3 11 3 2 3 10 5 2 3 11 4 2 3 10 4 2 3 10 3 2 3 12 5 2 3 |
|||
11 |
|||
Sentence length: 1203 |
|||
The 1000th word is 'in' and has 2 letters. Sentence length: 6279 |
|||
The 10000th word is 'in' and has 2 letters. Sentence length: 64140 |
|||
The 100000th word is 'one' and has 3 letters. Sentence length: 659474 |
|||
The 1000000th word is 'the' and has 3 letters. Sentence length: 7113621 |
|||
The 10000000th word is 'thousand' and has 8 letters. Sentence length: 70995756 |
|||
</pre> |
</pre> |
||