Решение на Думи на Фибоначи от Александър Иванов

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

Към профила на Александър Иванов

Резултати

  • 20 точки от тестове
  • 0 бонус точки
  • 20 точки общо
  • 20 успешни тест(а)
  • 0 неуспешни тест(а)

Код

pub struct FibIter {
f0: u32,
f1: u32,
}
pub struct RevFibIter {
f_last: u32,
f_prelast: u32,
}
impl FibIter {
#[allow(clippy::new_without_default)]
pub fn new() -> FibIter {
FibIter { f0: 1, f1: 1 }
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> u32 {
let return_value = self.f0;
(self.f0, self.f1) = (self.f1, self.f0 + self.f1);
return_value
}
pub fn rev(self) -> RevFibIter {
let last_element_returned_from_next = self.f1 - self.f0;
RevFibIter {
f_last: last_element_returned_from_next,
f_prelast: self.f0 - last_element_returned_from_next,
}
}
}
impl RevFibIter {
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<u32> {
let return_value = self.f_last;
if return_value == 0 {
return None;
}
(self.f_last, self.f_prelast) = (self.f_prelast, self.f_last - self.f_prelast);
Some(return_value)
}
}
pub fn fib_split(text: &str) -> Vec<String> {
let mut result = Vec::<String>::new();
let mut fib_iter = FibIter::new();
let mut word_current_length = fib_iter.next() as usize;
let mut buffer = String::new();
for x in text.chars() {
if buffer.chars().count() < word_current_length {
buffer.push(x); // x копиран
} else {
result.push(buffer); // ownership e преместен
buffer = x.to_string();
word_current_length = fib_iter.next() as usize;
}
}
result.push(buffer);
result // ownership e преместен
}
pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, &str) {
if n == 0 {
return (vec![], text);
}
let n = n as usize;
let mut result = Vec::<String>::new();
let mut fib_iter = FibIter::new();
let mut word_current_length = fib_iter.next() as usize;
let mut buffer = String::new();
let mut counter = 0_usize;
for x in text.chars() {
buffer.push(x); // x копиран
if buffer.chars().count() == word_current_length {
result.push(buffer); // ownership е преместен
counter += word_current_length;
if n == result.len() {
break;
}
buffer = String::new();
word_current_length = fib_iter.next() as usize;
}
}
if n > result.len() {
panic!("Not enough letters in text");
}
let string_left_start_byte = match text.char_indices().nth(counter) {
Some((index, _)) => index,
None => text.len(),
};
(result, &text[string_left_start_byte..]) // ownership на result е преместен
}
pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, &str) {
if n == 0 {
return (vec![], text);
}
let (mut result, leftover) = fib_split_n(text, n);
let n = n as usize;
let mut fib_iter = FibIter::new();
for _ in 0..n {
fib_iter.next();
}
let mut fib_iter_rev = fib_iter.rev();
let mut word_current_length = fib_iter_rev.next().unwrap() as usize;
let mut buffer = String::new();
let mut counter = 0_usize;
for x in leftover.chars() {
buffer.push(x); // x копиран
if buffer.chars().count() == word_current_length {
result.push(buffer); // ownership е преместен
counter += word_current_length;
if n == result.len() {
break;
}
buffer = String::new();
match fib_iter_rev.next() {
Some(current_element) => word_current_length = current_element as usize,
None => break,
}
}
}
if 2 * n > result.len() {
panic!("Not enough letters in text");
}
let string_left_start_byte = match leftover.char_indices().nth(counter) {
Some((index, _)) => index,
None => leftover.len(),
};
(result, &leftover[string_left_start_byte..]) // ownership на result е преместен
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////// TESTS ///////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[test]
fn test_basic() {
let mut fib_iter = FibIter::new();
fib_iter.next();
let mut rev_fib_iter: RevFibIter = fib_iter.rev();
rev_fib_iter.next();
let _words: Vec<String> = fib_split("Fibonacci words!");
let (_words, _rest): (Vec<String>, &str) = fib_split_n(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
1,
);
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
1,
);
}
#[test]
fn fib_iter_next() {
let mut fib_iter = FibIter::new();
for x in [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144] {
assert_eq!(fib_iter.next(), x);
}
}
#[test]
fn fib_rev_next_initial_state() {
let fib_iter = FibIter::new();
let mut fib_iter_rev = fib_iter.rev();
assert_eq!(fib_iter_rev.next(), Option::<u32>::None);
assert_eq!(fib_iter_rev.next(), Option::<u32>::None);
assert_eq!(fib_iter_rev.next(), Option::<u32>::None);
}
#[test]
fn fib_rev_next_further_state() {
let mut fib_iter = FibIter::new();
let sequence = [0; 10].map(|_| fib_iter.next());
let mut fib_iter_rev = fib_iter.rev();
for x in sequence.into_iter().rev() {
assert_eq!(fib_iter_rev.next(), Some(x));
}
assert_eq!(fib_iter_rev.next(), None);
assert_eq!(fib_iter_rev.next(), None);
}
#[test]
fn fib_split_happy_path() {
let _words: Vec<String> = fib_split("Fibonacci words!");
assert_eq!(_words, vec!["F", "i", "bo", "nac", "ci wo", "rds!"]);
let _words: Vec<String> = fib_split("Аз съм динозавър");
assert_eq!(_words, ["А", "з", " с", "ъм ", "диноз", "авър"]);
}
#[test]
fn fib_split_empty_text() {
let _words: Vec<String> = fib_split("");
assert_eq!(_words, [""]);
}
#[test]
fn fib_split_n_happy_path() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
6,
);
assert_eq!(
(_words, _rest),
(
["L", "o", "re", "m i", "psum ", "dolor si"]
.iter()
.map(|x| x.to_string())
.collect(),
"t amet, consectetur adipiscing elit."
)
);
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм динозавър", 4);
assert_eq!(
(_words, _rest),
(
["А", "з", " с", "ъм "]
.iter()
.map(|x| x.to_string())
.collect(),
"динозавър"
)
);
}
#[test]
fn fib_split_n_n_equal_zero_and_text_empty() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n("", 0);
assert_eq!((_words, _rest), (vec![], ""));
}
#[test]
fn fib_split_n_n_equal_zero() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм динозавър", 0);
assert_eq!((_words, _rest), (vec![], "Аз съм динозавър"));
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Lorem ipsum dolor si", 0);
assert_eq!((_words, _rest), (vec![], "Lorem ipsum dolor si"));
}
#[test]
fn fib_split_n_with_empty_leftover() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм ", 4);
assert_eq!(
(_words, _rest),
(
["А", "з", " с", "ъм "]
.iter()
.map(|x| x.to_string())
.collect(),
""
)
);
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Lorem ipsum dolor si", 6);
assert_eq!(
(_words, _rest),
(
["L", "o", "re", "m i", "psum ", "dolor si"]
.iter()
.map(|x| x.to_string())
.collect(),
""
)
);
}
#[test]
#[should_panic]
fn fib_split_n_not_enough_letters_non_ascii() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм динозавър", 6);
}
#[test]
#[should_panic]
fn fib_split_n_not_enough_letters_ascii() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Lorem ipsum dolor si", 7);
}
#[test]
fn fib_split_n_symmetric_n_equal_zero() {
let (_words, _rest): (Vec<String>, &str) =
fib_split_n_symmetric("Lorem ipsum dolor sit amet", 0);
assert_eq!((_words, _rest), (vec![], "Lorem ipsum dolor sit amet"));
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Нещо по-различно, нали", 0);
assert_eq!((_words, _rest), (vec![], "Нещо по-различно, нали"));
}
#[test]
fn fib_split_n_symmetric_n_equal_zero_and_text_empty() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("", 0);
assert_eq!((_words, _rest), (vec![], ""));
}
#[test]
fn fib_split_n_symmetric_empty_leftover() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Аз съм д", 3);
assert_eq!(
(_words, _rest),
(
["А", "з", " с", "ъм", " ", "д"]
.iter()
.map(|x| x.to_string())
.collect(),
""
)
);
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Lorem ipsum do", 4);
assert_eq!(
(_words, _rest),
(
["L", "o", "re", "m i", "psu", "m ", "d", "o"]
.iter()
.map(|x| x.to_string())
.collect(),
""
)
);
}
#[test]
fn fib_split_n_symmetric_happy_path() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Аз съм динозавър", 4);
assert_eq!(
(_words, _rest),
(
["А", "з", " с", "ъм ", "дин", "оз", "а", "в"]
.iter()
.map(|x| x.to_string())
.collect(),
"ър"
)
);
let (_words, _rest): (Vec<String>, &str) =
fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5);
assert_eq!(
(_words, _rest),
(
["L", "o", "re", "m i", "psum ", "dolor", " si", "t ", "a", "m"]
.iter()
.map(|x| x.to_string())
.collect(),
"et."
)
);
}
#[test]
#[should_panic]
fn fib_split_n_symmetric_not_enough_letters_non_ascii() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Аз съм динозавър", 5);
}
#[test]
#[should_panic]
fn fib_split_n_symmetric_not_enough_letters_ascii() {
let (_words, _rest): (Vec<String>, &str) =
fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 6);
}

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

Compiling solution v0.1.0 (/tmp/d20241104-1739405-1bthudc/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.92s
     Running tests/solution_test.rs (target/debug/deps/solution_test-1428e1090729d165)

running 20 tests
test solution_test::fib_iter ... ok
test solution_test::fib_split_ascii ... ok
test solution_test::fib_split_cyrillic ... ok
test solution_test::fib_split_empty ... ok
test solution_test::fib_split_n_ascii ... ok
test solution_test::fib_split_n_ascii_exact ... ok
test solution_test::fib_split_n_ascii_panic ... ok
test solution_test::fib_split_n_cyrillic ... ok
test solution_test::fib_split_n_cyrillic_exact ... ok
test solution_test::fib_split_n_cyrillic_panic ... ok
test solution_test::fib_split_n_symmetric_ascii ... ok
test solution_test::fib_split_n_symmetric_ascii_exact ... ok
test solution_test::fib_split_n_symmetric_cyrillic ... ok
test solution_test::fib_split_n_symmetric_ascii_panic ... ok
test solution_test::fib_split_n_symmetric_cyrillic_exact ... ok
test solution_test::fib_split_n_symmetric_cyrillic_panic ... ok
test solution_test::fib_split_n_symmetric_zero ... ok
test solution_test::fib_split_n_zero ... ok
test solution_test::rev_fib_iter ... ok
test solution_test::rev_fib_iter_empty ... ok

test result: ok. 20 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

История (3 версии и 0 коментара)

Александър качи първо решение на 27.10.2024 20:58 (преди 11 месеца)

Александър качи решение на 28.10.2024 15:43 (преди 11 месеца)

pub struct FibIter {
f0: u32,
f1: u32,
}
pub struct RevFibIter {
f_last: u32,
f_prelast: u32,
}
impl FibIter {
#[allow(clippy::new_without_default)]
pub fn new() -> FibIter {
FibIter { f0: 1, f1: 1 }
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> u32 {
let return_value = self.f0;
(self.f0, self.f1) = (self.f1, self.f0 + self.f1);
return_value
}
pub fn rev(self) -> RevFibIter {
let last_element_returned_from_next = self.f1 - self.f0;
RevFibIter {
f_last: last_element_returned_from_next,
f_prelast: self.f0 - last_element_returned_from_next,
}
}
}
impl RevFibIter {
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<u32> {
let return_value = self.f_last;
if return_value == 0 {
return None;
}
(self.f_last, self.f_prelast) = (self.f_prelast, self.f_last - self.f_prelast);
Some(return_value)
}
}
pub fn fib_split(text: &str) -> Vec<String> {
let mut result = Vec::<String>::new();
let mut fib_iter = FibIter::new();
let mut word_current_length = fib_iter.next() as usize;
let mut buffer = String::new();
for x in text.chars() {
if buffer.chars().count() < word_current_length {
- buffer.push(x); // x копиран
+ buffer.push(x); // x copied
} else {
- result.push(buffer); // ownership e преместен
+ result.push(buffer); // ownership moved
buffer = x.to_string();
word_current_length = fib_iter.next() as usize;
}
}
result.push(buffer);
- result // ownership e преместен
+ result // ownership moved
}
pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, &str) {
if n == 0 {
return (vec![], text);
}
let n = n as usize;
let mut result = Vec::<String>::new();
let mut fib_iter = FibIter::new();
let mut word_current_length = fib_iter.next() as usize;
let mut buffer = String::new();
let mut counter = 0_usize;
for x in text.chars() {
buffer.push(x); // x копиран
if buffer.chars().count() == word_current_length {
result.push(buffer); // ownership е преместен
counter += word_current_length;
if n == result.len() {
break;
}
buffer = String::new();
word_current_length = fib_iter.next() as usize;
}
}
if n > result.len() {
panic!("Not enough letters in text");
}
let string_left_start_byte = match text.char_indices().nth(counter) {
Some((index, _)) => index,
None => text.len(),
};
(result, &text[string_left_start_byte..]) // ownership на result е преместен
}
pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, &str) {
if n == 0 {
return (vec![], text);
}
let (mut result, leftover) = fib_split_n(text, n);
let n = n as usize;
let mut fib_iter = FibIter::new();
for _ in 0..n {
fib_iter.next();
}
let mut fib_iter_rev = fib_iter.rev();
let mut word_current_length = fib_iter_rev.next().unwrap() as usize;
let mut buffer = String::new();
let mut counter = 0_usize;
for x in leftover.chars() {
buffer.push(x); // x копиран
if buffer.chars().count() == word_current_length {
result.push(buffer); // ownership е преместен
counter += word_current_length;
if n == result.len() {
break;
}
buffer = String::new();
match fib_iter_rev.next() {
Some(current_element) => word_current_length = current_element as usize,
None => break,
}
}
}
if 2 * n > result.len() {
panic!("Not enough letters in text");
}
let string_left_start_byte = match leftover.char_indices().nth(counter) {
Some((index, _)) => index,
None => leftover.len(),
};
(result, &leftover[string_left_start_byte..]) // ownership на result е преместен
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////// TESTS ///////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#[test]
+fn test_basic() {
+ let mut fib_iter = FibIter::new();
+ fib_iter.next();
+
+ let mut rev_fib_iter: RevFibIter = fib_iter.rev();
+ rev_fib_iter.next();
+
+ let _words: Vec<String> = fib_split("Fibonacci words!");
+
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n(
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
+ 1,
+ );
+
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric(
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
+ 1,
+ );
+}
+
+#[test]
+fn fib_iter_next() {
+ let mut fib_iter = FibIter::new();
+
+ for x in [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144] {
+ assert_eq!(fib_iter.next(), x);
+ }
+}
+
+#[test]
+fn fib_rev_next_initial_state() {
+ let fib_iter = FibIter::new();
+ let mut fib_iter_rev = fib_iter.rev();
+
+ assert_eq!(fib_iter_rev.next(), Option::<u32>::None);
+ assert_eq!(fib_iter_rev.next(), Option::<u32>::None);
+ assert_eq!(fib_iter_rev.next(), Option::<u32>::None);
+}
+
+#[test]
+fn fib_rev_next_further_state() {
+ let mut fib_iter = FibIter::new();
+
+ let sequence = [0; 10].map(|_| fib_iter.next());
+
+ let mut fib_iter_rev = fib_iter.rev();
+
+ for x in sequence.into_iter().rev() {
+ assert_eq!(fib_iter_rev.next(), Some(x));
+ }
+
+ assert_eq!(fib_iter_rev.next(), None);
+ assert_eq!(fib_iter_rev.next(), None);
+}
+
+#[test]
+fn fib_split_happy_path() {
+ let _words: Vec<String> = fib_split("Fibonacci words!");
+ assert_eq!(_words, vec!["F", "i", "bo", "nac", "ci wo", "rds!"]);
+
+ let _words: Vec<String> = fib_split("Аз съм динозавър");
+ assert_eq!(_words, ["А", "з", " с", "ъм ", "диноз", "авър"]);
+}
+
+#[test]
+fn fib_split_empty_text() {
+ let _words: Vec<String> = fib_split("");
+ assert_eq!(_words, [""]);
+}
+
+#[test]
+fn fib_split_n_happy_path() {
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n(
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
+ 6,
+ );
+ assert_eq!(
+ (_words, _rest),
+ (
+ ["L", "o", "re", "m i", "psum ", "dolor si"]
+ .iter()
+ .map(|x| x.to_string())
+ .collect(),
+ "t amet, consectetur adipiscing elit."
+ )
+ );
+
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм динозавър", 4);
+ assert_eq!(
+ (_words, _rest),
+ (
+ ["А", "з", " с", "ъм "]
+ .iter()
+ .map(|x| x.to_string())
+ .collect(),
+ "динозавър"
+ )
+ );
+}
+
+#[test]
+fn fib_split_n_n_equal_zero_and_text_empty() {
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n("", 0);
+ assert_eq!((_words, _rest), (vec![], ""));
+}
+#[test]
+fn fib_split_n_n_equal_zero() {
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм динозавър", 0);
+ assert_eq!((_words, _rest), (vec![], "Аз съм динозавър"));
+
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n("Lorem ipsum dolor si", 0);
+ assert_eq!((_words, _rest), (vec![], "Lorem ipsum dolor si"));
+}
+
+#[test]
+fn fib_split_n_with_empty_leftover() {
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм ", 4);
+ assert_eq!(
+ (_words, _rest),
+ (
+ ["А", "з", " с", "ъм "]
+ .iter()
+ .map(|x| x.to_string())
+ .collect(),
+ ""
+ )
+ );
+
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n("Lorem ipsum dolor si", 6);
+ assert_eq!(
+ (_words, _rest),
+ (
+ ["L", "o", "re", "m i", "psum ", "dolor si"]
+ .iter()
+ .map(|x| x.to_string())
+ .collect(),
+ ""
+ )
+ );
+}
+
+#[test]
+#[should_panic]
+fn fib_split_n_not_enough_letters_non_ascii() {
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм динозавър", 6);
+}
+
+#[test]
+#[should_panic]
+fn fib_split_n_not_enough_letters_ascii() {
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n("Lorem ipsum dolor si", 7);
+}
+
+#[test]
+fn fib_split_n_symmetric_n_equal_zero() {
+ let (_words, _rest): (Vec<String>, &str) =
+ fib_split_n_symmetric("Lorem ipsum dolor sit amet", 0);
+ assert_eq!((_words, _rest), (vec![], "Lorem ipsum dolor sit amet"));
+
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Нещо по-различно, нали", 0);
+ assert_eq!((_words, _rest), (vec![], "Нещо по-различно, нали"));
+}
+
+#[test]
+fn fib_split_n_symmetric_n_equal_zero_and_text_empty() {
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("", 0);
+ assert_eq!((_words, _rest), (vec![], ""));
+}
+
+#[test]
+fn fib_split_n_symmetric_empty_leftover() {
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Аз съм д", 3);
+ assert_eq!(
+ (_words, _rest),
+ (
+ ["А", "з", " с", "ъм", " ", "д"]
+ .iter()
+ .map(|x| x.to_string())
+ .collect(),
+ ""
+ )
+ );
+
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Lorem ipsum do", 4);
+ assert_eq!(
+ (_words, _rest),
+ (
+ ["L", "o", "re", "m i", "psu", "m ", "d", "o"]
+ .iter()
+ .map(|x| x.to_string())
+ .collect(),
+ ""
+ )
+ );
+}
+
+#[test]
+fn fib_split_n_symmetric_happy_path() {
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Аз съм динозавър", 4);
+ assert_eq!(
+ (_words, _rest),
+ (
+ ["А", "з", " с", "ъм ", "дин", "оз", "а", "в"]
+ .iter()
+ .map(|x| x.to_string())
+ .collect(),
+ "ър"
+ )
+ );
+
+ let (_words, _rest): (Vec<String>, &str) =
+ fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5);
+ assert_eq!(
+ (_words, _rest),
+ (
+ ["L", "o", "re", "m i", "psum ", "dolor", " si", "t ", "a", "m"]
+ .iter()
+ .map(|x| x.to_string())
+ .collect(),
+ "et."
+ )
+ );
+}
+
+#[test]
+#[should_panic]
+fn fib_split_n_symmetric_not_enough_letters_non_ascii() {
+ let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Аз съм динозавър", 5);
+}
+
+#[test]
+#[should_panic]
+fn fib_split_n_symmetric_not_enough_letters_ascii() {
+ let (_words, _rest): (Vec<String>, &str) =
+ fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 6);
}

Александър качи решение на 28.10.2024 15:46 (преди 11 месеца)

pub struct FibIter {
f0: u32,
f1: u32,
}
pub struct RevFibIter {
f_last: u32,
f_prelast: u32,
}
impl FibIter {
#[allow(clippy::new_without_default)]
pub fn new() -> FibIter {
FibIter { f0: 1, f1: 1 }
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> u32 {
let return_value = self.f0;
(self.f0, self.f1) = (self.f1, self.f0 + self.f1);
return_value
}
pub fn rev(self) -> RevFibIter {
let last_element_returned_from_next = self.f1 - self.f0;
RevFibIter {
f_last: last_element_returned_from_next,
f_prelast: self.f0 - last_element_returned_from_next,
}
}
}
impl RevFibIter {
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<u32> {
let return_value = self.f_last;
if return_value == 0 {
return None;
}
(self.f_last, self.f_prelast) = (self.f_prelast, self.f_last - self.f_prelast);
Some(return_value)
}
}
pub fn fib_split(text: &str) -> Vec<String> {
let mut result = Vec::<String>::new();
let mut fib_iter = FibIter::new();
let mut word_current_length = fib_iter.next() as usize;
let mut buffer = String::new();
for x in text.chars() {
if buffer.chars().count() < word_current_length {
- buffer.push(x); // x copied
+ buffer.push(x); // x копиран
} else {
- result.push(buffer); // ownership moved
+ result.push(buffer); // ownership e преместен
buffer = x.to_string();
word_current_length = fib_iter.next() as usize;
}
}
result.push(buffer);
- result // ownership moved
+ result // ownership e преместен
}
pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, &str) {
if n == 0 {
return (vec![], text);
}
let n = n as usize;
let mut result = Vec::<String>::new();
let mut fib_iter = FibIter::new();
let mut word_current_length = fib_iter.next() as usize;
let mut buffer = String::new();
let mut counter = 0_usize;
for x in text.chars() {
buffer.push(x); // x копиран
if buffer.chars().count() == word_current_length {
result.push(buffer); // ownership е преместен
counter += word_current_length;
if n == result.len() {
break;
}
buffer = String::new();
word_current_length = fib_iter.next() as usize;
}
}
if n > result.len() {
panic!("Not enough letters in text");
}
let string_left_start_byte = match text.char_indices().nth(counter) {
Some((index, _)) => index,
None => text.len(),
};
(result, &text[string_left_start_byte..]) // ownership на result е преместен
}
pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, &str) {
if n == 0 {
return (vec![], text);
}
let (mut result, leftover) = fib_split_n(text, n);
let n = n as usize;
let mut fib_iter = FibIter::new();
for _ in 0..n {
fib_iter.next();
}
let mut fib_iter_rev = fib_iter.rev();
let mut word_current_length = fib_iter_rev.next().unwrap() as usize;
let mut buffer = String::new();
let mut counter = 0_usize;
for x in leftover.chars() {
buffer.push(x); // x копиран
if buffer.chars().count() == word_current_length {
result.push(buffer); // ownership е преместен
counter += word_current_length;
if n == result.len() {
break;
}
buffer = String::new();
match fib_iter_rev.next() {
Some(current_element) => word_current_length = current_element as usize,
None => break,
}
}
}
if 2 * n > result.len() {
panic!("Not enough letters in text");
}
let string_left_start_byte = match leftover.char_indices().nth(counter) {
Some((index, _)) => index,
None => leftover.len(),
};
(result, &leftover[string_left_start_byte..]) // ownership на result е преместен
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////// TESTS ///////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[test]
fn test_basic() {
let mut fib_iter = FibIter::new();
fib_iter.next();
let mut rev_fib_iter: RevFibIter = fib_iter.rev();
rev_fib_iter.next();
let _words: Vec<String> = fib_split("Fibonacci words!");
let (_words, _rest): (Vec<String>, &str) = fib_split_n(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
1,
);
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
1,
);
}
#[test]
fn fib_iter_next() {
let mut fib_iter = FibIter::new();
for x in [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144] {
assert_eq!(fib_iter.next(), x);
}
}
#[test]
fn fib_rev_next_initial_state() {
let fib_iter = FibIter::new();
let mut fib_iter_rev = fib_iter.rev();
assert_eq!(fib_iter_rev.next(), Option::<u32>::None);
assert_eq!(fib_iter_rev.next(), Option::<u32>::None);
assert_eq!(fib_iter_rev.next(), Option::<u32>::None);
}
#[test]
fn fib_rev_next_further_state() {
let mut fib_iter = FibIter::new();
let sequence = [0; 10].map(|_| fib_iter.next());
let mut fib_iter_rev = fib_iter.rev();
for x in sequence.into_iter().rev() {
assert_eq!(fib_iter_rev.next(), Some(x));
}
assert_eq!(fib_iter_rev.next(), None);
assert_eq!(fib_iter_rev.next(), None);
}
#[test]
fn fib_split_happy_path() {
let _words: Vec<String> = fib_split("Fibonacci words!");
assert_eq!(_words, vec!["F", "i", "bo", "nac", "ci wo", "rds!"]);
let _words: Vec<String> = fib_split("Аз съм динозавър");
assert_eq!(_words, ["А", "з", " с", "ъм ", "диноз", "авър"]);
}
#[test]
fn fib_split_empty_text() {
let _words: Vec<String> = fib_split("");
assert_eq!(_words, [""]);
}
#[test]
fn fib_split_n_happy_path() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
6,
);
assert_eq!(
(_words, _rest),
(
["L", "o", "re", "m i", "psum ", "dolor si"]
.iter()
.map(|x| x.to_string())
.collect(),
"t amet, consectetur adipiscing elit."
)
);
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм динозавър", 4);
assert_eq!(
(_words, _rest),
(
["А", "з", " с", "ъм "]
.iter()
.map(|x| x.to_string())
.collect(),
"динозавър"
)
);
}
#[test]
fn fib_split_n_n_equal_zero_and_text_empty() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n("", 0);
assert_eq!((_words, _rest), (vec![], ""));
}
#[test]
fn fib_split_n_n_equal_zero() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм динозавър", 0);
assert_eq!((_words, _rest), (vec![], "Аз съм динозавър"));
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Lorem ipsum dolor si", 0);
assert_eq!((_words, _rest), (vec![], "Lorem ipsum dolor si"));
}
#[test]
fn fib_split_n_with_empty_leftover() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм ", 4);
assert_eq!(
(_words, _rest),
(
["А", "з", " с", "ъм "]
.iter()
.map(|x| x.to_string())
.collect(),
""
)
);
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Lorem ipsum dolor si", 6);
assert_eq!(
(_words, _rest),
(
["L", "o", "re", "m i", "psum ", "dolor si"]
.iter()
.map(|x| x.to_string())
.collect(),
""
)
);
}
#[test]
#[should_panic]
fn fib_split_n_not_enough_letters_non_ascii() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Аз съм динозавър", 6);
}
#[test]
#[should_panic]
fn fib_split_n_not_enough_letters_ascii() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n("Lorem ipsum dolor si", 7);
}
#[test]
fn fib_split_n_symmetric_n_equal_zero() {
let (_words, _rest): (Vec<String>, &str) =
fib_split_n_symmetric("Lorem ipsum dolor sit amet", 0);
assert_eq!((_words, _rest), (vec![], "Lorem ipsum dolor sit amet"));
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Нещо по-различно, нали", 0);
assert_eq!((_words, _rest), (vec![], "Нещо по-различно, нали"));
}
#[test]
fn fib_split_n_symmetric_n_equal_zero_and_text_empty() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("", 0);
assert_eq!((_words, _rest), (vec![], ""));
}
#[test]
fn fib_split_n_symmetric_empty_leftover() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Аз съм д", 3);
assert_eq!(
(_words, _rest),
(
["А", "з", " с", "ъм", " ", "д"]
.iter()
.map(|x| x.to_string())
.collect(),
""
)
);
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Lorem ipsum do", 4);
assert_eq!(
(_words, _rest),
(
["L", "o", "re", "m i", "psu", "m ", "d", "o"]
.iter()
.map(|x| x.to_string())
.collect(),
""
)
);
}
#[test]
fn fib_split_n_symmetric_happy_path() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Аз съм динозавър", 4);
assert_eq!(
(_words, _rest),
(
["А", "з", " с", "ъм ", "дин", "оз", "а", "в"]
.iter()
.map(|x| x.to_string())
.collect(),
"ър"
)
);
let (_words, _rest): (Vec<String>, &str) =
fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5);
assert_eq!(
(_words, _rest),
(
["L", "o", "re", "m i", "psum ", "dolor", " si", "t ", "a", "m"]
.iter()
.map(|x| x.to_string())
.collect(),
"et."
)
);
}
#[test]
#[should_panic]
fn fib_split_n_symmetric_not_enough_letters_non_ascii() {
let (_words, _rest): (Vec<String>, &str) = fib_split_n_symmetric("Аз съм динозавър", 5);
}
#[test]
#[should_panic]
fn fib_split_n_symmetric_not_enough_letters_ascii() {
let (_words, _rest): (Vec<String>, &str) =
fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 6);
}