Решение на FMI Buzz от Антонина Ускова

Обратно към всички решения

Към профила на Антонина Ускова

Резултати

  • 15 точки от тестове
  • 1 бонус точка
  • 16 точки общо
  • 10 успешни тест(а)
  • 0 неуспешни тест(а)

Код

/// Вход: променлива `n`, която описва броя елементи, които ще генерираме в резултата.
///
/// За всяко число от 1 до `n` включително, искаме съответстващия елемент в резултата да е:
///
/// - String със съдържание "Fizz" ако числото се дели на 3, но не на 5
/// - String със съдържание "Buzz" ако числото се дели на 5, но не на 3
/// - String със съдържание "Fizzbuzz" ако числото се дели и на 3, и на 5
/// - Числото конвертирано до низ, във всички други случаи
///
/// Тоест, във `fizzbuzz(3)`, първия елемент ще бъде `String::from("1")`, втория
/// `String::from("2")`, последния `String::from("Fizz")`.
///
/// Ако `n` е 0, очакваме празен вектор за резултат.
///
pub fn fizzbuzz(n: usize) -> Vec<String> {
custom_buzz(n, 3, 5)
}
/// Вход:
/// - променлива `n`, която описва броя елементи, които ще генерираме в резултата.
/// - променливи `k1` и `k2`, които са двата делителя, които ще използваме за заместване.
///
/// За всяко число от 1 до `n` включително, искаме съответстващия елемент в резултата да е:
///
/// - String със съдържание "Fizz" ако числото се дели на k1, но не на k2
/// - String със съдържание "Buzz" ако числото се дели на k2, но не на k1
/// - String със съдържание "Fizzbuzz" ако числото се дели и на k1, и на k2
/// - Числото конвертирано до низ, във всички други случаи
///
/// Ако `n` е 0, очакваме празен вектор за резултат.
/// Ако `k1` или `k2` са 0 или 1, очакваме функцията да panic-не с каквото съобщение изберете.
///
pub fn custom_buzz(n: usize, k1: u8, k2: u8) -> Vec<String> {
let fizz_buzzer = FizzBuzzer{
k1,
k2,
labels: [String::from("Fizz"), String::from("Buzz"), String::from("Fizzbuzz")],
};
fizz_buzzer.take(n)
}
/// Параметри:
/// - полета `k1` и `k2`, които са двата делителя, които ще използваме за заместване.
/// - поле `labels`, които са трите етикета, които съответстват на коефициентите
///
/// Ако `n` е 0, очакваме празен вектор за резултат.
/// Ако `k1` или `k2` са 0 или 1, очакваме функцията да panic-не с каквото съобщение изберете.
///
pub struct FizzBuzzer {
pub k1: u8,
pub k2: u8,
pub labels: [String; 3],
}
impl FizzBuzzer {
/// За всяко число от 1 до `n` включително, искаме съответстващия елемент в резултата да е:
///
/// - Първия String от полето `labels` ако числото се дели на k1, но не на k2
/// - Втория String от полето `labels` ако числото се дели на k2, но не на k1
/// - Третия String от полето `labels` ако числото се дели и на k1, и на k2
/// - Числото конвертирано до низ, във всички други случаи
///
pub fn take(&self, n: usize) -> Vec<String> {
if self.k1 == 0 || self.k1 == 1 {
panic!("k1 must be different than 0 and 1. k1 is: {}.", self.k1);
}
if self.k2 == 0 || self.k2 == 1 {
panic!("k2 must be different than 0 and 1. k2 is: {}.", self.k2);
}
let mut vec: Vec<String> = Vec::with_capacity(n);
for i in 1..(n + 1){
match i {
i if (i % (self.k1 as usize)) == 0 &&
(i % (self.k2 as usize)) == 0 =>
vec.push(self.labels[2].clone()),
i if i % (self.k1 as usize) == 0 =>
vec.push(self.labels[0].clone()),
i if i % (self.k2 as usize) == 0 =>
vec.push(self.labels[1].clone()),
i => vec.push(i.to_string()),
}
};
vec
}
/// Параметъра `index` указва кой етикет от полето `labels` променяме, от 0 до 2. Ако подадения
/// `index` е извън тези рамки, очакваме функцията да panic-не.
///
/// Стойността `value` е низа, който ще сложим на този индекс в полето `labels`.
///
pub fn change_label(&mut self, index: usize, value: &String) {
// It will panic is the index is out of bounds anyway.
self.labels[index] = value.clone();
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn when_zero_vec_is_empty() {
assert_eq!(Vec::new() as Vec<String>, get_fizz_buzzer(3, 5, None).take(0));
assert_eq!(Vec::new() as Vec<String>, custom_buzz(0, 3, 5));
assert_eq!(Vec::new() as Vec<String>, fizzbuzz(0));
}
#[test]
fn vec_has_size_n() {
let n = 10;
assert_eq!(n, get_fizz_buzzer(3, 5, None).take(n).len());
assert_eq!(n, custom_buzz(n, 3, 5).len());
assert_eq!(n, fizzbuzz(n).len());
}
#[test]
fn fizzbuzz_is_correct(){
let expected = vec![
1.to_string(),
2.to_string(),
String::from("Fizz"), // 3
4.to_string(),
String::from("Buzz"), // 5
String::from("Fizz"), // 6
7.to_string(),
8.to_string(),
String::from("Fizz"), // 9
String::from("Buzz"), // 10
11.to_string(),
String::from("Fizz"), // 12
13.to_string(),
14.to_string(),
String::from("Fizzbuzz"), // 15
16.to_string(),
];
assert_eq!(expected, fizzbuzz(16));
}
#[test]
fn custom_fizzbuzz_is_correct(){
let expected = vec![
1.to_string(),
String::from("Fizz"), // 2
String::from("Buzz"), // 3
String::from("Fizz"), // 4
5.to_string(),
String::from("Fizzbuzz"), // 6
7.to_string(),
];
assert_eq!(expected, custom_buzz(7, 2, 3));
}
#[test]
fn fizz_buzzer_take_is_correct(){
let labels = [String::from("Жълто"), String::from("Синьо"), String::from("Зелено")];
let expected = vec![
1.to_string(),
String::from("Жълто"), // 2
String::from("Синьо"), // 3
String::from("Жълто"), // 4
5.to_string(),
String::from("Зелено"), // 6
7.to_string(),
];
assert_eq!(expected, get_fizz_buzzer(2, 3, Some(labels)).take(7));
}
#[test]
#[should_panic]
fn k1_should_not_be_0_in_custom_buzz(){
custom_buzz(0, 0, 5);
}
#[test]
#[should_panic]
fn k1_should_not_be_1_in_custom_buzz(){
custom_buzz(0, 1, 5);
}
#[test]
#[should_panic]
fn k2_should_not_be_0_in_custom_buzz(){
custom_buzz(0, 3, 0);
}
#[test]
#[should_panic]
fn k2_should_not_be_1_in_custom_buzz(){
custom_buzz(0, 3, 1);
}
#[test]
#[should_panic]
fn k1_should_not_be_0_in_fizz_buzzer(){
get_fizz_buzzer(0, 5, None).take(0);
}
#[test]
#[should_panic]
fn k1_should_not_be_1_in_fizz_buzzer(){
get_fizz_buzzer(1, 5, None).take(0);
}
#[test]
#[should_panic]
fn k2_should_not_be_0_in_fizz_buzzer(){
get_fizz_buzzer(3, 0, None).take(0);
}
#[test]
#[should_panic]
fn k2_should_not_be_1_in_fizz_buzzer(){
get_fizz_buzzer(3, 1, None).take(0);
}
#[test]
fn change_label_changes_label(){
let mut fuzz_buzzer = FizzBuzzer{
k1: 3,
k2: 5,
labels: [String::from("Fizz"), String::from("Buzz"), String::from("Fizzbuzz")],
};
assert_eq!(String::from("Fizz"), fuzz_buzzer.labels[0]);
fuzz_buzzer.change_label(0, &String::from("Cat"));
assert_eq!(String::from("Cat"), fuzz_buzzer.labels[0]);

Още един assertion тук щеше да е добре -- да извикаш take-а на fizzbuzzer-а, за да провериш, че промяната на label-а афектира това, което take прави. От друга страна, признавам че това включва тестване на два отделни метода. Но да кажем, че аз бих направил този тест поне.

}
#[test]
#[should_panic]
fn change_label_panics_on_invalid_index(){
let mut fuzz_buzzer = FizzBuzzer{
k1: 3,
k2: 5,
labels: [String::from("Fizz"), String::from("Buzz"), String::from("Fizzbuzz")],
};
fuzz_buzzer.change_label(3, &String::from("Cat"));
}
fn get_fizz_buzzer(k1: u8, k2: u8,fizz_buzzer_opt: Option<[String; 3]>) -> FizzBuzzer {
let default_labels = [String::from("Fizz"), String::from("Buzz"), String::from("Fizzbuzz")];
let labels = fizz_buzzer_opt.unwrap_or(default_labels);
FizzBuzzer{
k1,
k2,
labels,
}
}
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20201028-2816268-18t5liu/solution)
    Finished test [unoptimized + debuginfo] target(s) in 2.91s
     Running target/debug/deps/solution-ebb42508826ef2b4

running 15 tests
test tests::change_label_changes_label ... ok
test tests::change_label_panics_on_invalid_index ... ok
test tests::custom_fizzbuzz_is_correct ... ok
test tests::fizz_buzzer_take_is_correct ... ok
test tests::fizzbuzz_is_correct ... ok
test tests::k1_should_not_be_0_in_custom_buzz ... ok
test tests::k1_should_not_be_0_in_fizz_buzzer ... ok
test tests::k1_should_not_be_1_in_custom_buzz ... ok
test tests::k1_should_not_be_1_in_fizz_buzzer ... ok
test tests::k2_should_not_be_0_in_custom_buzz ... ok
test tests::k2_should_not_be_0_in_fizz_buzzer ... ok
test tests::k2_should_not_be_1_in_custom_buzz ... ok
test tests::k2_should_not_be_1_in_fizz_buzzer ... ok
test tests::vec_has_size_n ... ok
test tests::when_zero_vec_is_empty ... ok

test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

     Running target/debug/deps/solution_test-9e954a53ed808c89

running 10 tests
test solution_test::test_change_label_basic ... ok
test solution_test::test_change_label_invalid ... ok
test solution_test::test_classic1 ... ok
test solution_test::test_classic2 ... ok
test solution_test::test_coefficients1 ... ok
test solution_test::test_coefficients2 ... ok
test solution_test::test_coefficients_invalid ... ok
test solution_test::test_struct_basic ... ok
test solution_test::test_struct_invalid ... ok
test solution_test::test_zeroes ... ok

test result: ok. 10 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

   Doc-tests solution

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

История (1 версия и 2 коментара)

Антонина качи първо решение на 23.10.2020 19:18 (преди почти 5 години)

Добра работа с тестовете -- оставянето на коментари с числото на което съответства етикета е добра идея, ще ми се да се бях сетил като писах тестовете за домашното :).