const DICT: [&str; 24] = [
"N", "o m", "ore", " bottle", "s", " of beer", " on", " th", "e ", "wall", ", ", "n", ".\n", "Go to", "st", " and ", "buy som", "m", "99", "Take", " it ", "down", "pass", "around", ];
fn calculate_length(strings: &[(usize, usize)]) -> usize {
strings.iter().fold(0, |a, (b, c)| a + b * DICT[*c].len())
}
fn common_length() -> usize {
calculate_length(&[(3, 3), (3, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (2, 12)])
}
fn allocate_string(strings: &[(usize, usize)], more: usize) -> String {
String::with_capacity(common_length() + calculate_length(strings) + more)
}
fn modify_string(mut string: String, prefices_and_indices: &[(&str, &[usize])]) -> String {
prefices_and_indices.iter().for_each(|(prefix, indices)| {
string.push_str(prefix);
indices.iter().for_each(|index| string.push_str(DICT[*index]));
});
string
}
fn allocate_and_modify_verse(strings: &[(usize, usize)], more: usize, prefices_and_indices: &[(&str, &[usize])]) -> String {
let mut out = String::with_capacity(common_length() + calculate_length(strings) + more);
prefices_and_indices.iter().for_each(|(prefix, indices)| {
out.push_str(prefix);
indices.iter().for_each(|index| out.push_str(DICT[*index]));
});
out
}
pub fn verse(n: u32) -> String {
match n {
0 => {
allocate_and_modify_verse(&[(1, 0), (2, 1), (4, 2), (3, 4), (1, 11), (1, 13), (1, 7), (2, 8), (1, 14), (1, 15), (1, 16), (1, 17), (1, 18)], 0, &[(&"", &[0usize, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3, 4, 5, 12, 13, 7, 8, 14, 2, 15, 16, 8, 17, 2, 10, 18, 3, 4, 5, 6, 7, 8, 9, 12])])
}
1 => {
let n_string = n.to_string();
allocate_and_modify_verse(&[(1, 19), (2, 20), (1, 21), (1, 15), (1, 22), (1, 23), (1, 11), (1, 1), (1, 2), (1, 4)], 2, &[(&n_string, &[3usize, 5, 6, 7, 8, 9, 10]), (&n_string, &[3usize, 5, 12, 19, 20, 21, 15, 22, 20, 23, 10, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12])])
}
2 => {
let (n_string, m_string) = (n.to_string(), (n - 1).to_string());
allocate_and_modify_verse(&[(2, 4), (1, 19), (1, 6), (1, 8), (1, 21), (1, 15), (1, 22), (1, 20), (1, 23)], 2 * n_string.len() + m_string.len(), &[(&n_string, &[3usize, 4, 5, 6, 7, 8, 9, 10]), (&n_string, &[3usize, 4, 5, 12, 19, 6, 8, 21, 15, 22, 20, 23, 10]), (&m_string, &[3, 5, 6, 7, 8, 9, 12])])
}
_ => {
let (n_string, m_string) = (n.to_string(), (n - 1).to_string());
allocate_and_modify_verse(&[(3, 4), (1, 19), (1, 6), (1, 8), (1, 21), (1, 15), (1, 22), (1, 20), (1, 23)], 2 * n_string.len() + m_string.len(), &[(&n_string, &[3usize, 4, 5, 6, 7, 8, 9, 10]), (&n_string, &[3usize, 4, 5, 12, 19, 6, 8, 21, 15, 22, 20, 23, 10]), (&m_string, &[3, 4, 5, 6, 7, 8, 9, 12])])
}
}
}
pub fn sing(start: u32, end: u32) -> String {
"".to_string()
}