Решение на Думи на Фибоначи от Габриела Димитрова

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

Към профила на Габриела Димитрова

Резултати

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

Код

use std::vec;
fn safe_slice_head(text: &str, i: usize) -> String {
text.chars().take(i).collect()
}
fn safe_slice_tail(text: &str, i: usize) -> String {
text.chars().skip(i).collect()
}
pub fn fib_split(text: &str) -> Vec<String> {
let mut fib_iter = FibIter::new();
let mut vec: Vec<String> = Vec::new();
fn fib_split_rec(text: &str, fib_iter: &mut FibIter, vector: &mut Vec<String>) -> Vec<String> {
let fib: usize = fib_iter.next() as usize;
if text.is_empty() {
// println!("Debug: {:?}", vector);
return vector.clone();
} else if text.len() < fib {
vector.push(text.to_string());
// println!("Debug: {:?}", vector);
return vector.clone();
}
vector.push(safe_slice_head(text, fib).to_string());
// println!("Debug: {:?}", vector);
fib_split_rec(&safe_slice_tail(text, fib), fib_iter, vector)
}
fib_split_rec(text, &mut fib_iter, &mut vec)
}
pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, String) {
let mut fib_iter = FibIter::new();
let mut vec: Vec<String> = Vec::new();
// helper func
fn fib_split_n_rec(text: &str, fib_iter: &mut FibIter, vector: &mut Vec<String>, n_curr: u32)
-> Vec<String> {
let fib: usize = fib_iter.next() as usize;
if n_curr <= 0 {
return vector.clone();
}
if text.len() < fib {
panic!("Някакво съобщение за грешка!");
}
vector.push(safe_slice_head(text, fib).to_string());
fib_split_n_rec(&safe_slice_tail(text, fib), fib_iter, vector, n_curr - 1)
}
let vec = fib_split_n_rec(text, &mut fib_iter, &mut vec, n);
let fib_sum = fib_iter.sum as usize;
// println!("Debug: {}", fib_sum);
(vec, safe_slice_tail(text, fib_sum))
}
pub struct FibIter {
current: u32,
next: u32,
sum: u32, // sumata na vs chisla koito sme iterirali dosega
}
impl FibIter {
pub fn new() -> FibIter {
FibIter { current: 0, next: 1, sum: 0 }
}
pub fn next(&mut self) -> u32 {
self.sum += self.current;
let temp = self.current;
self.current = self.next;
self.next = temp + self.next;
self.current
}
// Can be improved by adding vec<u32> field in FibIter
// instead of generating the sequence up to n again
pub fn rev(self) -> RevFibIter {
let mut fib = FibIter::new();
let mut arr = Vec::new();
for _ in 0..self.current {
arr.insert(0, fib.next());
}
let len = arr.len();
arr.insert(0,0);
// println!("DEBUG: {:?}", arr);
RevFibIter { current: self.current, curr_idx: 0, arr }
}
}
pub struct RevFibIter {
current: u32,
curr_idx: usize,
arr: Vec<u32>,
}
impl RevFibIter {
pub fn next(&mut self) -> Option<u32> {
self.curr_idx = self.curr_idx + 1;
if self.curr_idx >= self.arr.len() {
return None;
}
self.current = self.arr[self.curr_idx as usize];
Some(self.current)
}
}
pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, String) {
let mut fib_iter = FibIter::new();
for _ in 0..n { // generate the fibonacci series up to n
fib_iter.next();
}
let mut rev_iter = fib_iter.rev();
let (mut vec, mut rest) = fib_split_n(text, n); // process first half of text
let sum = 2 * (text.len() - rest.len()); // length of the processed text
// iterative this time
fn fib_split_n_rev_rec(text: &str, fib_iter: &mut RevFibIter, vector: &mut Vec<String>,
n_curr: u32) -> Vec<String> {
if n_curr <= 0 { // дъно на рекурсията
return vector.clone();
}
match fib_iter.next() {
Some(fib) => {
if text.len() < fib as usize {
panic!("Някакво съобщение за грешка!");
}
vector.push(safe_slice_head(text, fib as usize).to_string());
return fib_split_n_rev_rec(&safe_slice_tail(text, fib as usize), fib_iter, vector, n_curr - 1)
}
None => panic!("what?")
}
}
let mut _vec: Vec<String> = Vec::new();
let vec_rev = fib_split_n_rev_rec(rest.as_str(), &mut rev_iter, &mut _vec, n);
vec.extend(vec_rev);
(vec, safe_slice_tail(text, sum))
}
// ----------------------------------------------- //
// -- Tests -------------------------------------- //
// ----------------------------------------------- //
#[cfg(test)]
mod tests {
use super::*; //
#[test]
fn test1() {
//let fib = FibIter::new();
//for _number in 0..10 {
// println!("{}", fib.next());
//}
let (vec, rest) = fib_split_n("Lorem ipsum dolor sit amet.", 6);
println!("{:?} {:?}", vec, rest);
let (vec, rest) =
fib_split_n_symmetric("Лорем ipsum dolor sit amet.", 5);
println!("{:?} {:?}", vec, rest);
}
#[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!");
assert_eq!(words, &["F", "i", "bo", "nac", "ci wo", "rds!"]);
let (words, rest) = fib_split_n("Lorem ipsum dolor sit amet.", 6);
assert_eq!(words, &["L", "o", "re", "m i", "psum ", "dolor si"]);
assert_eq!(rest, "t amet.");
let (words, rest) = fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5);
assert_eq!(words, &["L", "o", "re", "m i", "psum ", "dolor", " si", "t ", "a", "m"]);
assert_eq!(rest, "et.");
}
}

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

Compiling solution v0.1.0 (/tmp/d20241104-1739405-1bt7jl4/solution)
warning: unused import: `std::vec`
 --> src/lib.rs:1:5
  |
1 | use std::vec;
  |     ^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused variable: `len`
  --> src/lib.rs:91:13
   |
91 |         let len = arr.len();
   |             ^^^ help: if this is intentional, prefix it with an underscore: `_len`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: variable does not need to be mutable
   --> src/lib.rs:121:19
    |
121 |     let (mut vec, mut rest) = fib_split_n(text, n); // process first half of text
    |                   ----^^^^
    |                   |
    |                   help: remove this `mut`
    |
    = note: `#[warn(unused_mut)]` on by default

warning: `solution` (lib) generated 3 warnings
    Finished test [unoptimized + debuginfo] target(s) in 1.25s
     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_empty ... ok
test solution_test::fib_split_cyrillic ... 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 ... FAILED
test solution_test::fib_split_n_symmetric_ascii ... FAILED
test solution_test::fib_split_n_symmetric_ascii_exact ... FAILED
test solution_test::fib_split_n_symmetric_ascii_panic ... ok
test solution_test::fib_split_n_symmetric_cyrillic ... FAILED
test solution_test::fib_split_n_symmetric_cyrillic_exact ... FAILED
test solution_test::fib_split_n_symmetric_zero ... ok
test solution_test::fib_split_n_symmetric_cyrillic_panic ... ok
test solution_test::fib_split_n_zero ... ok
test solution_test::rev_fib_iter ... FAILED
test solution_test::rev_fib_iter_empty ... ok

failures:

---- solution_test::fib_split_n_cyrillic_panic stdout ----
thread 'solution_test::fib_split_n_cyrillic_panic' panicked at 'assertion failed: catch_unwind(|| fib_split_n(\"манджа_with_грозде\", 6)).is_err()', tests/solution_test.rs:119:5

---- solution_test::fib_split_n_symmetric_ascii stdout ----
thread 'solution_test::fib_split_n_symmetric_ascii' panicked at 'what?', src/lib.rs:140:21

---- solution_test::fib_split_n_symmetric_ascii_exact stdout ----
thread 'solution_test::fib_split_n_symmetric_ascii_exact' panicked at 'what?', src/lib.rs:140:21

---- solution_test::fib_split_n_symmetric_cyrillic stdout ----
thread 'solution_test::fib_split_n_symmetric_cyrillic' panicked at 'assertion failed: `(left == right)`
  left: `"жа_with_грозде"`,
 right: `"нджа_with_грозде"`', tests/solution_test.rs:161:5

---- solution_test::fib_split_n_symmetric_cyrillic_exact stdout ----
thread 'solution_test::fib_split_n_symmetric_cyrillic_exact' panicked at 'what?', src/lib.rs:140:21

---- solution_test::rev_fib_iter stdout ----
thread 'solution_test::rev_fib_iter' panicked at 'assertion failed: `(left == right)`
  left: `Some(233)`,
 right: `Some(13)`', tests/solution_test.rs:28:5


failures:
    solution_test::fib_split_n_cyrillic_panic
    solution_test::fib_split_n_symmetric_ascii
    solution_test::fib_split_n_symmetric_ascii_exact
    solution_test::fib_split_n_symmetric_cyrillic
    solution_test::fib_split_n_symmetric_cyrillic_exact
    solution_test::rev_fib_iter

test result: FAILED. 14 passed; 6 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `--test solution_test`

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

Габриела качи първо решение на 31.10.2024 17:28 (преди 11 месеца)

Габриела качи решение на 31.10.2024 17:44 (преди 11 месеца)

use std::vec;
+fn safe_slice_head(text: &str, i: usize) -> String {
+ text.chars().take(i).collect()
+}
+fn safe_slice_tail(text: &str, i: usize) -> String {
+ text.chars().skip(i).collect()
+}
+
pub fn fib_split(text: &str) -> Vec<String> {
let mut fib_iter = FibIter::new();
let mut vec: Vec<String> = Vec::new();
fn fib_split_rec(text: &str, fib_iter: &mut FibIter, vector: &mut Vec<String>) -> Vec<String> {
let fib: usize = fib_iter.next() as usize;
if text.is_empty() {
// println!("Debug: {:?}", vector);
return vector.clone();
} else if text.len() < fib {
vector.push(text.to_string());
// println!("Debug: {:?}", vector);
return vector.clone();
}
- vector.push(text[0..fib].to_string());
+ vector.push(safe_slice_head(text, fib).to_string());
// println!("Debug: {:?}", vector);
- fib_split_rec(&text[fib..], fib_iter, vector)
+ fib_split_rec(&safe_slice_tail(text, fib), fib_iter, vector)
}
fib_split_rec(text, &mut fib_iter, &mut vec)
}
-pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, &str) {
+pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, String) {
let mut fib_iter = FibIter::new();
let mut vec: Vec<String> = Vec::new();
// helper func
fn fib_split_n_rec(text: &str, fib_iter: &mut FibIter, vector: &mut Vec<String>, n_curr: u32)
-> Vec<String> {
let fib: usize = fib_iter.next() as usize;
if n_curr <= 0 {
return vector.clone();
}
if text.len() < fib {
panic!("Някакво съобщение за грешка!");
}
- vector.push(text[0..fib].to_string());
- fib_split_n_rec(&text[fib..], fib_iter, vector, n_curr - 1)
+ vector.push(safe_slice_head(text, fib).to_string());
+ fib_split_n_rec(&safe_slice_tail(text, fib), fib_iter, vector, n_curr - 1)
}
let vec = fib_split_n_rec(text, &mut fib_iter, &mut vec, n);
let fib_sum = fib_iter.sum as usize;
// println!("Debug: {}", fib_sum);
- (vec, &text[fib_sum..])
+ (vec, safe_slice_head(text, fib_sum))
}
pub struct FibIter {
current: u32,
next: u32,
sum: u32, // sumata na vs chisla koito sme iterirali dosega
}
impl FibIter {
pub fn new() -> FibIter {
FibIter { current: 0, next: 1, sum: 0 }
}
pub fn next(&mut self) -> u32 {
self.sum += self.current;
let temp = self.current;
self.current = self.next;
self.next = temp + self.next;
self.current
}
// Can be improved by adding vec<u32> field in FibIter
// instead of generating the sequence up to n again
pub fn rev(self) -> RevFibIter {
let mut fib = FibIter::new();
let mut arr = Vec::new();
for _ in 0..self.current {
arr.insert(0, fib.next());
}
let len = arr.len();
arr.insert(0,0);
// println!("DEBUG: {:?}", arr);
RevFibIter { current: self.current, curr_idx: 0, arr }
}
}
pub struct RevFibIter {
current: u32,
curr_idx: usize,
arr: Vec<u32>,
}
impl RevFibIter {
pub fn next(&mut self) -> Option<u32> {
self.curr_idx = self.curr_idx + 1;
if self.curr_idx >= self.arr.len() {
return None;
}
self.current = self.arr[self.curr_idx as usize];
Some(self.current)
}
}
-pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, &str) {
+pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, String) {
let mut fib_iter = FibIter::new();
for _ in 0..n { // generate the fibonacci series up to n
fib_iter.next();
}
let mut rev_iter = fib_iter.rev();
let (mut vec, mut rest) = fib_split_n(text, n); // process first half of text
let sum = 2 * (text.len() - rest.len()); // length of the processed text
// iterative this time
fn fib_split_n_rev_rec(text: &str, fib_iter: &mut RevFibIter, vector: &mut Vec<String>,
n_curr: u32) -> Vec<String> {
if n_curr <= 0 { // дъно на рекурсията
return vector.clone();
}
match fib_iter.next() {
Some(fib) => {
if text.len() < fib as usize {
panic!("Някакво съобщение за грешка!");
}
- vector.push(text[0..fib as usize].to_string());
- return fib_split_n_rev_rec(&text[fib as usize..], fib_iter, vector, n_curr - 1)
+ vector.push(safe_slice_head(text, fib as usize).to_string());
+ return fib_split_n_rev_rec(&safe_slice_tail(text, fib as usize), fib_iter, vector, n_curr - 1)
}
None => panic!("what?")
}
}
let mut _vec: Vec<String> = Vec::new();
- let vec_rev = fib_split_n_rev_rec(rest, &mut rev_iter, &mut _vec, n);
+ let vec_rev = fib_split_n_rev_rec(rest.as_str(), &mut rev_iter, &mut _vec, n);
vec.extend(vec_rev);
- (vec, &text[sum..])
+ (vec, safe_slice_head(text, sum))
}
// ----------------------------------------------- //
// -- Tests -------------------------------------- //
// ----------------------------------------------- //
#[cfg(test)]
mod tests {
use super::*; //
#[test]
fn test1() {
//let fib = FibIter::new();
//for _number in 0..10 {
// println!("{}", fib.next());
//}
- let (vec, rest) = fib_split_n("Hello there! ABC abcd", 6);
+ let (vec, rest) = fib_split_n("Хелло тхере! ABC abcd", 6);
println!("{:?} {:?}", vec, rest);
let (vec, rest) =
- fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5);
+ fib_split_n_symmetric("Лорем ipsum dolor sit amet.", 5);
println!("{:?} {:?}", vec, rest);
}
#[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!");
assert_eq!(words, &["F", "i", "bo", "nac", "ci wo", "rds!"]);
let (words, rest) = fib_split_n("Lorem ipsum dolor sit amet.", 6);
assert_eq!(words, &["L", "o", "re", "m i", "psum ", "dolor si"]);
assert_eq!(rest, "t amet.");
let (words, rest) = fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5);
assert_eq!(words, &["L", "o", "re", "m i", "psum ", "dolor", " si", "t ", "a", "m"]);
assert_eq!(rest, "et.");
}
}

Габриела качи решение на 31.10.2024 17:49 (преди 11 месеца)

use std::vec;
-fn safe_slice_head(text: &str, i: usize) -> String {
- text.chars().take(i).collect()
-}
-fn safe_slice_tail(text: &str, i: usize) -> String {
- text.chars().skip(i).collect()
-}
-
pub fn fib_split(text: &str) -> Vec<String> {
let mut fib_iter = FibIter::new();
let mut vec: Vec<String> = Vec::new();
fn fib_split_rec(text: &str, fib_iter: &mut FibIter, vector: &mut Vec<String>) -> Vec<String> {
let fib: usize = fib_iter.next() as usize;
if text.is_empty() {
// println!("Debug: {:?}", vector);
return vector.clone();
} else if text.len() < fib {
vector.push(text.to_string());
// println!("Debug: {:?}", vector);
return vector.clone();
}
- vector.push(safe_slice_head(text, fib).to_string());
+ vector.push(text[0..fib].to_string());
// println!("Debug: {:?}", vector);
- fib_split_rec(&safe_slice_tail(text, fib), fib_iter, vector)
+ fib_split_rec(&text[fib..], fib_iter, vector)
}
fib_split_rec(text, &mut fib_iter, &mut vec)
}
-pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, String) {
+pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, &str) {
let mut fib_iter = FibIter::new();
let mut vec: Vec<String> = Vec::new();
// helper func
fn fib_split_n_rec(text: &str, fib_iter: &mut FibIter, vector: &mut Vec<String>, n_curr: u32)
-> Vec<String> {
let fib: usize = fib_iter.next() as usize;
if n_curr <= 0 {
return vector.clone();
}
if text.len() < fib {
panic!("Някакво съобщение за грешка!");
}
- vector.push(safe_slice_head(text, fib).to_string());
- fib_split_n_rec(&safe_slice_tail(text, fib), fib_iter, vector, n_curr - 1)
+ vector.push(text[0..fib].to_string());
+ fib_split_n_rec(&text[fib..], fib_iter, vector, n_curr - 1)
}
let vec = fib_split_n_rec(text, &mut fib_iter, &mut vec, n);
let fib_sum = fib_iter.sum as usize;
// println!("Debug: {}", fib_sum);
- (vec, safe_slice_head(text, fib_sum))
+ (vec, &text[fib_sum..])
}
pub struct FibIter {
current: u32,
next: u32,
sum: u32, // sumata na vs chisla koito sme iterirali dosega
}
impl FibIter {
pub fn new() -> FibIter {
FibIter { current: 0, next: 1, sum: 0 }
}
pub fn next(&mut self) -> u32 {
self.sum += self.current;
let temp = self.current;
self.current = self.next;
self.next = temp + self.next;
self.current
}
// Can be improved by adding vec<u32> field in FibIter
// instead of generating the sequence up to n again
pub fn rev(self) -> RevFibIter {
let mut fib = FibIter::new();
let mut arr = Vec::new();
for _ in 0..self.current {
arr.insert(0, fib.next());
}
let len = arr.len();
arr.insert(0,0);
// println!("DEBUG: {:?}", arr);
RevFibIter { current: self.current, curr_idx: 0, arr }
}
}
pub struct RevFibIter {
current: u32,
curr_idx: usize,
arr: Vec<u32>,
}
impl RevFibIter {
pub fn next(&mut self) -> Option<u32> {
self.curr_idx = self.curr_idx + 1;
if self.curr_idx >= self.arr.len() {
return None;
}
self.current = self.arr[self.curr_idx as usize];
Some(self.current)
}
}
-pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, String) {
+pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, &str) {
let mut fib_iter = FibIter::new();
for _ in 0..n { // generate the fibonacci series up to n
fib_iter.next();
}
let mut rev_iter = fib_iter.rev();
let (mut vec, mut rest) = fib_split_n(text, n); // process first half of text
let sum = 2 * (text.len() - rest.len()); // length of the processed text
// iterative this time
fn fib_split_n_rev_rec(text: &str, fib_iter: &mut RevFibIter, vector: &mut Vec<String>,
n_curr: u32) -> Vec<String> {
if n_curr <= 0 { // дъно на рекурсията
return vector.clone();
}
match fib_iter.next() {
Some(fib) => {
if text.len() < fib as usize {
panic!("Някакво съобщение за грешка!");
}
- vector.push(safe_slice_head(text, fib as usize).to_string());
- return fib_split_n_rev_rec(&safe_slice_tail(text, fib as usize), fib_iter, vector, n_curr - 1)
+ vector.push(text[0..fib as usize].to_string());
+ return fib_split_n_rev_rec(&text[fib as usize..], fib_iter, vector, n_curr - 1)
}
None => panic!("what?")
}
}
let mut _vec: Vec<String> = Vec::new();
- let vec_rev = fib_split_n_rev_rec(rest.as_str(), &mut rev_iter, &mut _vec, n);
+ let vec_rev = fib_split_n_rev_rec(rest, &mut rev_iter, &mut _vec, n);
vec.extend(vec_rev);
- (vec, safe_slice_head(text, sum))
+ (vec, &text[sum..])
}
// ----------------------------------------------- //
// -- Tests -------------------------------------- //
// ----------------------------------------------- //
#[cfg(test)]
mod tests {
use super::*; //
#[test]
fn test1() {
//let fib = FibIter::new();
//for _number in 0..10 {
// println!("{}", fib.next());
//}
- let (vec, rest) = fib_split_n("Хелло тхере! ABC abcd", 6);
+ let (vec, rest) = fib_split_n("Hello there! ABC abcd", 6);
println!("{:?} {:?}", vec, rest);
let (vec, rest) =
- fib_split_n_symmetric("Лорем ipsum dolor sit amet.", 5);
+ fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5);
println!("{:?} {:?}", vec, rest);
}
#[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!");
assert_eq!(words, &["F", "i", "bo", "nac", "ci wo", "rds!"]);
let (words, rest) = fib_split_n("Lorem ipsum dolor sit amet.", 6);
assert_eq!(words, &["L", "o", "re", "m i", "psum ", "dolor si"]);
assert_eq!(rest, "t amet.");
let (words, rest) = fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5);
assert_eq!(words, &["L", "o", "re", "m i", "psum ", "dolor", " si", "t ", "a", "m"]);
assert_eq!(rest, "et.");
}
}

Габриела качи решение на 31.10.2024 17:59 (преди 11 месеца)

use std::vec;
+fn safe_slice_head(text: &str, i: usize) -> String {
+ text.chars().take(i).collect()
+}
+fn safe_slice_tail(text: &str, i: usize) -> String {
+ text.chars().skip(i).collect()
+}
+
pub fn fib_split(text: &str) -> Vec<String> {
let mut fib_iter = FibIter::new();
let mut vec: Vec<String> = Vec::new();
fn fib_split_rec(text: &str, fib_iter: &mut FibIter, vector: &mut Vec<String>) -> Vec<String> {
let fib: usize = fib_iter.next() as usize;
if text.is_empty() {
// println!("Debug: {:?}", vector);
return vector.clone();
} else if text.len() < fib {
vector.push(text.to_string());
// println!("Debug: {:?}", vector);
return vector.clone();
}
- vector.push(text[0..fib].to_string());
+ vector.push(safe_slice_head(text, fib).to_string());
// println!("Debug: {:?}", vector);
- fib_split_rec(&text[fib..], fib_iter, vector)
+ fib_split_rec(&safe_slice_tail(text, fib), fib_iter, vector)
}
fib_split_rec(text, &mut fib_iter, &mut vec)
}
-pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, &str) {
+pub fn fib_split_n(text: &str, n: u32) -> (Vec<String>, String) {
let mut fib_iter = FibIter::new();
let mut vec: Vec<String> = Vec::new();
// helper func
fn fib_split_n_rec(text: &str, fib_iter: &mut FibIter, vector: &mut Vec<String>, n_curr: u32)
-> Vec<String> {
let fib: usize = fib_iter.next() as usize;
if n_curr <= 0 {
return vector.clone();
}
if text.len() < fib {
panic!("Някакво съобщение за грешка!");
}
- vector.push(text[0..fib].to_string());
- fib_split_n_rec(&text[fib..], fib_iter, vector, n_curr - 1)
+ vector.push(safe_slice_head(text, fib).to_string());
+ fib_split_n_rec(&safe_slice_tail(text, fib), fib_iter, vector, n_curr - 1)
}
let vec = fib_split_n_rec(text, &mut fib_iter, &mut vec, n);
let fib_sum = fib_iter.sum as usize;
// println!("Debug: {}", fib_sum);
- (vec, &text[fib_sum..])
+ (vec, safe_slice_tail(text, fib_sum))
}
pub struct FibIter {
current: u32,
next: u32,
sum: u32, // sumata na vs chisla koito sme iterirali dosega
}
impl FibIter {
pub fn new() -> FibIter {
FibIter { current: 0, next: 1, sum: 0 }
}
pub fn next(&mut self) -> u32 {
self.sum += self.current;
let temp = self.current;
self.current = self.next;
self.next = temp + self.next;
self.current
}
// Can be improved by adding vec<u32> field in FibIter
// instead of generating the sequence up to n again
pub fn rev(self) -> RevFibIter {
let mut fib = FibIter::new();
let mut arr = Vec::new();
for _ in 0..self.current {
arr.insert(0, fib.next());
}
let len = arr.len();
arr.insert(0,0);
// println!("DEBUG: {:?}", arr);
RevFibIter { current: self.current, curr_idx: 0, arr }
}
}
pub struct RevFibIter {
current: u32,
curr_idx: usize,
arr: Vec<u32>,
}
impl RevFibIter {
pub fn next(&mut self) -> Option<u32> {
self.curr_idx = self.curr_idx + 1;
if self.curr_idx >= self.arr.len() {
return None;
}
self.current = self.arr[self.curr_idx as usize];
Some(self.current)
}
}
-pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, &str) {
+pub fn fib_split_n_symmetric(text: &str, n: u32) -> (Vec<String>, String) {
let mut fib_iter = FibIter::new();
for _ in 0..n { // generate the fibonacci series up to n
fib_iter.next();
}
let mut rev_iter = fib_iter.rev();
let (mut vec, mut rest) = fib_split_n(text, n); // process first half of text
let sum = 2 * (text.len() - rest.len()); // length of the processed text
// iterative this time
fn fib_split_n_rev_rec(text: &str, fib_iter: &mut RevFibIter, vector: &mut Vec<String>,
- n_curr: u32) -> Vec<String> {
+ n_curr: u32) -> Vec<String> {
if n_curr <= 0 { // дъно на рекурсията
return vector.clone();
}
match fib_iter.next() {
Some(fib) => {
if text.len() < fib as usize {
panic!("Някакво съобщение за грешка!");
}
- vector.push(text[0..fib as usize].to_string());
- return fib_split_n_rev_rec(&text[fib as usize..], fib_iter, vector, n_curr - 1)
+ vector.push(safe_slice_head(text, fib as usize).to_string());
+ return fib_split_n_rev_rec(&safe_slice_tail(text, fib as usize), fib_iter, vector, n_curr - 1)
}
None => panic!("what?")
}
}
let mut _vec: Vec<String> = Vec::new();
- let vec_rev = fib_split_n_rev_rec(rest, &mut rev_iter, &mut _vec, n);
+ let vec_rev = fib_split_n_rev_rec(rest.as_str(), &mut rev_iter, &mut _vec, n);
vec.extend(vec_rev);
- (vec, &text[sum..])
+ (vec, safe_slice_tail(text, sum))
}
// ----------------------------------------------- //
// -- Tests -------------------------------------- //
// ----------------------------------------------- //
#[cfg(test)]
mod tests {
use super::*; //
#[test]
fn test1() {
//let fib = FibIter::new();
//for _number in 0..10 {
// println!("{}", fib.next());
//}
- let (vec, rest) = fib_split_n("Hello there! ABC abcd", 6);
+ let (vec, rest) = fib_split_n("Lorem ipsum dolor sit amet.", 6);
println!("{:?} {:?}", vec, rest);
let (vec, rest) =
- fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5);
+ fib_split_n_symmetric("Лорем ipsum dolor sit amet.", 5);
println!("{:?} {:?}", vec, rest);
}
#[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!");
assert_eq!(words, &["F", "i", "bo", "nac", "ci wo", "rds!"]);
let (words, rest) = fib_split_n("Lorem ipsum dolor sit amet.", 6);
assert_eq!(words, &["L", "o", "re", "m i", "psum ", "dolor si"]);
assert_eq!(rest, "t amet.");
let (words, rest) = fib_split_n_symmetric("Lorem ipsum dolor sit amet.", 5);
assert_eq!(words, &["L", "o", "re", "m i", "psum ", "dolor", " si", "t ", "a", "m"]);
assert_eq!(rest, "et.");
}
}