Решение на Думи на Фибоначи от Ясен Ефремов
Резултати
- 20 точки от тестове
- 0 бонус точки
- 20 точки общо
- 20 успешни тест(а)
- 0 неуспешни тест(а)
Код
pub struct FibIter {
a: u32,
b: u32,
i: u32
}
impl FibIter {
pub fn new() -> FibIter {
FibIter { a: 1, b: 1, i: 0 }
}
pub fn next(&mut self) -> u32 {
let next = match self.i {
0 => 1,
1 => 1,
_ => {
self.b = self.a + self.b;
self.a = self.b - self.a;
self.b
}
};
self.i += 1;
next
}
pub fn rev(self) -> RevFibIter {
RevFibIter { a: self.a , b: self.b, i: self.i, j: 0}
}
}
pub fn fib_split(text: &str) -> Vec<String> {
let mut words: Vec<String> = Vec::new();
let mut fib_iter = FibIter::new();
let mut word = String::new();
let mut j = fib_iter.next() as usize;
for (i, c) in text.chars().enumerate() {
word.push(c);
if i == (j - 1) {
words.push(word);
word = String::new();
j += fib_iter.next() as usize;
}
}
if !word.is_empty() { words.push(word); }
words
}
pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, &str) {
let mut words: Vec<String> = Vec::new();
let mut fib_iter = FibIter::new();
let mut word = String::new();
let mut fib_index = fib_iter.next() as usize;
let mut last_pos: usize = 0;
let mut exact: bool = true;
for (i, (j, c)) in text.char_indices().enumerate() {
last_pos = j;
if words.len() == n as usize {
exact = false;
break;
}
word.push(c);
if i == (fib_index - 1) && words.len() < n as usize {
words.push(word);
word = String::new();
fib_index += fib_iter.next() as usize;
}
}
if words.len() < n as usize { panic!("text too short!"); }
if exact {
(words, "")
} else {
(words, &text[last_pos..])
}
}
pub struct RevFibIter {
a: u32,
b: u32,
i: u32,
j: u32
}
impl RevFibIter {
pub fn next(&mut self) -> Option<u32> {
let next = match self.j {
_ if self.i == 0 => return None,
0 => Some(self.b),
1 => Some(self.a),
_ => {
self.a = self.b - self.a;
self.b = self.b - self.a;
Some(self.a)
}
};
self.j += 1;
self.i -= 1;
next
}
}
pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, &str) {
let mut words: Vec<String> = Vec::new();
if n == 0 { return (words, text); }
let mut fib_iter = FibIter::new();
let mut word = String::new();
let mut fib_index = fib_iter.next() as usize;
let mut last_pos: usize = 0;
let mut chars = text.char_indices().enumerate();
while let Some((i, (j, c))) = chars.next() {
last_pos = j;
word.push(c);
if i == fib_index - 1 {
words.push(word);
word = String::new();
if words.len() != n as usize {
fib_index += fib_iter.next() as usize;
} else {
break;
}
}
}
let mut rev_fib_iter = fib_iter.rev();
if let Some(next) = rev_fib_iter.next() {
fib_index += next as usize;
}
let mut exact = true;
while let Some((i, (j, c))) = chars.next() {
last_pos = j;
if words.len() == 2*n as usize {
exact = false;
break;
}
word.push(c);
if i == fib_index - 1 {
words.push(word);
word = String::new();
fib_index += match rev_fib_iter.next() {
Some(next) => next as usize,
None => 0
};
}
}
if words.len() < 2*n as usize { panic!("text too short!") }
if exact { (words, "") }
else { (words, &text[last_pos..]) }
}
#[test]
fn test_fib() {
let mut fib_iter = FibIter::new();
assert_eq!(fib_iter.next(), 1);
assert_eq!(fib_iter.next(), 1);
assert_eq!(fib_iter.next(), 2);
assert_eq!(fib_iter.next(), 3);
assert_eq!(fib_iter.next(), 5);
assert_eq!(fib_iter.next(), 8);
let mut rev_fib_iter = fib_iter.rev();
assert_eq!(rev_fib_iter.next(), Some(8));
assert_eq!(rev_fib_iter.next(), Some(5));
assert_eq!(rev_fib_iter.next(), Some(3));
assert_eq!(rev_fib_iter.next(), Some(2));
assert_eq!(rev_fib_iter.next(), Some(1));
assert_eq!(rev_fib_iter.next(), Some(1));
assert_eq!(rev_fib_iter.next(), None);
assert_eq!(rev_fib_iter.next(), None);
assert_eq!(rev_fib_iter.next(), None);
let mut fib_iter = FibIter::new();
assert_eq!(fib_iter.next(), 1);
let mut rev_fib_iter = fib_iter.rev();
assert_eq!(rev_fib_iter.next(), Some(1));
assert_eq!(rev_fib_iter.next(), None);
let mut fib_iter = FibIter::new();
assert_eq!(fib_iter.next(), 1);
assert_eq!(fib_iter.next(), 1);
let mut rev_fib_iter = fib_iter.rev();
assert_eq!(rev_fib_iter.next(), Some(1));
assert_eq!(rev_fib_iter.next(), Some(1));
assert_eq!(rev_fib_iter.next(), None);
}
#[test]
fn test_split() {
assert_eq!(fib_split("Fibonacci words!"), vec!["F", "i", "bo", "nac", "ci wo", "rds!"]);
assert_eq!(fib_split(""), Vec::<String>::new());
assert_eq!(fib_split("a"), vec!["a"]);
assert_eq!(fib_split("ab"), vec!["a", "b"]);
assert_eq!(fib_split("abc"), vec!["a", "b", "c"]);
assert_eq!(fib_split("abcd"), vec!["a", "b", "cd"]);
assert_eq!(fib_split("Фибоначчи уордс!"), vec!["Ф", "и", "бо", "нач", "чи уо", "рдс!"]);
assert_eq!(fib_split("Ф"), vec!["Ф"]);
assert_eq!(fib_split("Фи"), vec!["Ф", "и"]);
assert_eq!(fib_split("Фиби"), vec!["Ф", "и", "би"]);
assert_eq!(fib_split("Фибиди"), vec!["Ф", "и", "би", "ди"]);
}
#[test]
fn test_split_n() {
assert_eq!(fib_split_n("Lorem ipsum dolor sit amet.", 6),
(vec!["L", "o", "re", "m i", "psum ", "dolor si"].iter().map(|s| s.to_string()).collect(), "t amet."));
assert_eq!(fib_split_n("", 0),
(Vec::<String>::new(), ""));
assert_eq!(fib_split_n("L", 0),
(Vec::<String>::new(), "L"));
assert_eq!(fib_split_n("Lorem ipsum dolor sit amet.", 0),
(Vec::<String>::new(), "Lorem ipsum dolor sit amet."));
assert_eq!(fib_split_n("Lorem ipsum dolor sit amet.", 1),
(vec!["L"].iter().map(|s| s.to_string()).collect(), "orem ipsum dolor sit amet."));
assert_eq!(fib_split_n("L", 1),
(vec!["L"].iter().map(|s| s.to_string()).collect(), ""));
assert_eq!(fib_split_n("Lore", 3),
(vec!["L", "o", "re"].iter().map(|s| s.to_string()).collect(), ""));
assert_eq!(fib_split_n("Лорем ипсум долор сит амет.", 3),
(vec!["Л", "о", "ре"].iter().map(|s| s.to_string()).collect(), "м ипсум долор сит амет."));
assert_eq!(fib_split_n("Лорем ипсум долор сит амет.", 4),
(vec!["Л", "о", "ре", "м и"].iter().map(|s| s.to_string()).collect(), "псум долор сит амет."));
}
#[test]
fn test_split_symmetric() {
assert_eq!(fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5),
(vec!["L", "o", "re", "m i", "psum ", "dolor", " si", "t ", "a", "m"].iter().map(|s| s.to_string()).collect(), "et."));
assert_eq!(fib_split_n_symmetric("", 0),
(Vec::<String>::new(), ""));
assert_eq!(fib_split_n_symmetric("Ю", 0),
(Vec::<String>::new(), "Ю"));
assert_eq!(fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 0),
(Vec::<String>::new(), "Lorem ipsum dolor sit amet."));
assert_eq!(fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 1),
(vec!["L", "o"].iter().map(|s| s.to_string()).collect(), "rem ipsum dolor sit amet."));
assert_eq!(fib_split_n_symmetric("Lorem ipsum dolor sit am", 5),
(vec!["L", "o", "re", "m i", "psum ", "dolor", " si", "t ", "a", "m"].iter().map(|s| s.to_string()).collect(), ""));
assert_eq!(fib_split_n_symmetric("Лорем ипсум долор сит ам", 5),
(vec!["Л", "о", "ре", "м и", "псум ", "долор", " си", "т ", "а", "м"].iter().map(|s| s.to_string()).collect(), ""));
}
#[test]
#[should_panic]
fn test_split_n_panic() {
fib_split_n("", 1);
// fib_split_n("Lorem ипсум", 5);
}
#[test]
#[should_panic]
fn test_split_symmetric_panic() {
fib_split_n_symmetric("Л", 1);
// fib_split_n_symmetric("Лорем ипсум долор sit a", 5);
}
Лог от изпълнението
Compiling solution v0.1.0 (/tmp/d20241104-1739405-18z6dye/solution) Finished test [unoptimized + debuginfo] target(s) in 1.14s 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_cyrillic ... ok test solution_test::fib_split_n_ascii_panic ... 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_ascii_panic ... ok test solution_test::fib_split_n_symmetric_cyrillic ... 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
История (2 версии и 0 коментара)
Ясен качи решение на 30.10.2024 14:55 (преди 11 месеца)
pub struct FibIter {
a: u32,
b: u32,
i: u32
}
impl FibIter {
pub fn new() -> FibIter {
FibIter { a: 1, b: 1, i: 0 }
}
pub fn next(&mut self) -> u32 {
let next = match self.i {
- 0 => 1,
+ 0 => 1,
1 => 1,
_ => {
self.b = self.a + self.b;
self.a = self.b - self.a;
self.b
}
};
self.i += 1;
next
}
pub fn rev(self) -> RevFibIter {
- RevFibIter { a: self.a , b: self.b, i: 0}
+ RevFibIter { a: self.a , b: self.b, i: self.i, j: 0}
}
}
pub fn fib_split(text: &str) -> Vec<String> {
let mut words: Vec<String> = Vec::new();
let mut fib_iter = FibIter::new();
let mut word = String::new();
let mut j = fib_iter.next() as usize;
for (i, c) in text.chars().enumerate() {
word.push(c);
if i == (j - 1) {
words.push(word);
word = String::new();
j += fib_iter.next() as usize;
}
}
if !word.is_empty() { words.push(word); }
words
}
pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, &str) {
let mut words: Vec<String> = Vec::new();
let mut fib_iter = FibIter::new();
let mut word = String::new();
let mut fib_index = fib_iter.next() as usize;
let mut last_pos: usize = 0;
let mut exact: bool = true;
for (i, (j, c)) in text.char_indices().enumerate() {
last_pos = j;
if words.len() == n as usize {
exact = false;
break;
}
word.push(c);
if i == (fib_index - 1) && words.len() < n as usize {
words.push(word);
word = String::new();
fib_index += fib_iter.next() as usize;
}
}
if words.len() < n as usize { panic!("text too short!"); }
if exact {
(words, "")
} else {
(words, &text[last_pos..])
}
}
pub struct RevFibIter {
a: u32,
b: u32,
- i: u32
+ i: u32,
+ j: u32
}
impl RevFibIter {
pub fn next(&mut self) -> Option<u32> {
- let next = match self.i {
- _ if self.b == 1 => None,
+ let next = match self.j {
+ _ if self.i == 0 => return None,
0 => Some(self.b),
1 => Some(self.a),
_ => {
self.a = self.b - self.a;
self.b = self.b - self.a;
Some(self.a)
}
};
- self.i += 1;
+ self.j += 1;
+ self.i -= 1;
next
}
}
pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, &str) {
let mut words: Vec<String> = Vec::new();
+ if n == 0 { return (words, text); }
+
let mut fib_iter = FibIter::new();
let mut word = String::new();
let mut fib_index = fib_iter.next() as usize;
let mut last_pos: usize = 0;
let mut chars = text.char_indices().enumerate();
- let mut exact: bool = true;
while let Some((i, (j, c))) = chars.next() {
- if words.len() == n as usize { break; }
last_pos = j;
word.push(c);
if i == fib_index - 1 {
words.push(word);
word = String::new();
if words.len() != n as usize {
fib_index += fib_iter.next() as usize;
} else {
break;
}
}
}
let mut rev_fib_iter = fib_iter.rev();
- if let Some(f) = rev_fib_iter.next() {
- fib_index += f as usize;
- } else if !words.is_empty() {
- if let Some((j, _)) = chars.next() {
- return (words, &text[j..]);
- }
- } else {
- return (words, &text[last_pos..]);
+ if let Some(next) = rev_fib_iter.next() {
+ fib_index += next as usize;
}
- let mut done = false;
+ let mut exact = true;
while let Some((i, (j, c))) = chars.next() {
last_pos = j;
- if done {
+ if words.len() == 2*n as usize {
exact = false;
break;
}
word.push(c);
if i == fib_index - 1 {
words.push(word);
word = String::new();
fib_index += match rev_fib_iter.next() {
- Some(i) => i as usize,
- None => { done = true; 0 }
+ Some(next) => next as usize,
+ None => 0
};
}
}
if words.len() < 2*n as usize { panic!("text too short!") }
- if exact {
- (words, "")
- } else {
- (words, &text[last_pos..])
- }
+ if exact { (words, "") }
+ else { (words, &text[last_pos..]) }
+}
+
+
+#[test]
+fn test_fib() {
+ let mut fib_iter = FibIter::new();
+ assert_eq!(fib_iter.next(), 1);
+ assert_eq!(fib_iter.next(), 1);
+ assert_eq!(fib_iter.next(), 2);
+ assert_eq!(fib_iter.next(), 3);
+ assert_eq!(fib_iter.next(), 5);
+ assert_eq!(fib_iter.next(), 8);
+
+ let mut rev_fib_iter = fib_iter.rev();
+ assert_eq!(rev_fib_iter.next(), Some(8));
+ assert_eq!(rev_fib_iter.next(), Some(5));
+ assert_eq!(rev_fib_iter.next(), Some(3));
+ assert_eq!(rev_fib_iter.next(), Some(2));
+ assert_eq!(rev_fib_iter.next(), Some(1));
+ assert_eq!(rev_fib_iter.next(), Some(1));
+ assert_eq!(rev_fib_iter.next(), None);
+ assert_eq!(rev_fib_iter.next(), None);
+ assert_eq!(rev_fib_iter.next(), None);
+
+ let mut fib_iter = FibIter::new();
+ assert_eq!(fib_iter.next(), 1);
+
+ let mut rev_fib_iter = fib_iter.rev();
+ assert_eq!(rev_fib_iter.next(), Some(1));
+ assert_eq!(rev_fib_iter.next(), None);
+
+ let mut fib_iter = FibIter::new();
+ assert_eq!(fib_iter.next(), 1);
+ assert_eq!(fib_iter.next(), 1);
+
+ let mut rev_fib_iter = fib_iter.rev();
+ assert_eq!(rev_fib_iter.next(), Some(1));
+ assert_eq!(rev_fib_iter.next(), Some(1));
+ assert_eq!(rev_fib_iter.next(), None);
+}
+
+#[test]
+fn test_split() {
+ assert_eq!(fib_split("Fibonacci words!"), vec!["F", "i", "bo", "nac", "ci wo", "rds!"]);
+ assert_eq!(fib_split(""), Vec::<String>::new());
+ assert_eq!(fib_split("a"), vec!["a"]);
+ assert_eq!(fib_split("ab"), vec!["a", "b"]);
+ assert_eq!(fib_split("abc"), vec!["a", "b", "c"]);
+ assert_eq!(fib_split("abcd"), vec!["a", "b", "cd"]);
+
+ assert_eq!(fib_split("Фибоначчи уордс!"), vec!["Ф", "и", "бо", "нач", "чи уо", "рдс!"]);
+ assert_eq!(fib_split("Ф"), vec!["Ф"]);
+ assert_eq!(fib_split("Фи"), vec!["Ф", "и"]);
+ assert_eq!(fib_split("Фиби"), vec!["Ф", "и", "би"]);
+ assert_eq!(fib_split("Фибиди"), vec!["Ф", "и", "би", "ди"]);
+}
+
+#[test]
+fn test_split_n() {
+ assert_eq!(fib_split_n("Lorem ipsum dolor sit amet.", 6),
+ (vec!["L", "o", "re", "m i", "psum ", "dolor si"].iter().map(|s| s.to_string()).collect(), "t amet."));
+
+ assert_eq!(fib_split_n("", 0),
+ (Vec::<String>::new(), ""));
+ assert_eq!(fib_split_n("L", 0),
+ (Vec::<String>::new(), "L"));
+ assert_eq!(fib_split_n("Lorem ipsum dolor sit amet.", 0),
+ (Vec::<String>::new(), "Lorem ipsum dolor sit amet."));
+ assert_eq!(fib_split_n("Lorem ipsum dolor sit amet.", 1),
+ (vec!["L"].iter().map(|s| s.to_string()).collect(), "orem ipsum dolor sit amet."));
+ assert_eq!(fib_split_n("L", 1),
+ (vec!["L"].iter().map(|s| s.to_string()).collect(), ""));
+ assert_eq!(fib_split_n("Lore", 3),
+ (vec!["L", "o", "re"].iter().map(|s| s.to_string()).collect(), ""));
+
+ assert_eq!(fib_split_n("Лорем ипсум долор сит амет.", 3),
+ (vec!["Л", "о", "ре"].iter().map(|s| s.to_string()).collect(), "м ипсум долор сит амет."));
+ assert_eq!(fib_split_n("Лорем ипсум долор сит амет.", 4),
+ (vec!["Л", "о", "ре", "м и"].iter().map(|s| s.to_string()).collect(), "псум долор сит амет."));
+}
+
+#[test]
+fn test_split_symmetric() {
+ assert_eq!(fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5),
+ (vec!["L", "o", "re", "m i", "psum ", "dolor", " si", "t ", "a", "m"].iter().map(|s| s.to_string()).collect(), "et."));
+
+ assert_eq!(fib_split_n_symmetric("", 0),
+ (Vec::<String>::new(), ""));
+ assert_eq!(fib_split_n_symmetric("Ю", 0),
+ (Vec::<String>::new(), "Ю"));
+ assert_eq!(fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 0),
+ (Vec::<String>::new(), "Lorem ipsum dolor sit amet."));
+ assert_eq!(fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 1),
+ (vec!["L", "o"].iter().map(|s| s.to_string()).collect(), "rem ipsum dolor sit amet."));
+ assert_eq!(fib_split_n_symmetric("Lorem ipsum dolor sit am", 5),
+ (vec!["L", "o", "re", "m i", "psum ", "dolor", " si", "t ", "a", "m"].iter().map(|s| s.to_string()).collect(), ""));
+
+ assert_eq!(fib_split_n_symmetric("Лорем ипсум долор сит ам", 5),
+ (vec!["Л", "о", "ре", "м и", "псум ", "долор", " си", "т ", "а", "м"].iter().map(|s| s.to_string()).collect(), ""));
+}
+
+#[test]
+#[should_panic]
+fn test_split_n_panic() {
+ fib_split_n("", 1);
+ // fib_split_n("Lorem ипсум", 5);
+}
+
+#[test]
+#[should_panic]
+fn test_split_symmetric_panic() {
+ fib_split_n_symmetric("Л", 1);
+ // fib_split_n_symmetric("Лорем ипсум долор sit a", 5);
}