Решение на Text Info от Георги Божинов

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

Към профила на Георги Божинов

Резултати

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

Код

use std::collections::HashMap;
use std::vec::Vec;
pub struct TextInfo {
text: String,
alphabets: HashMap<String, String>,
ends_of_sentences: Vec<char>,
}
fn find_in_vector<T: Eq>(vec: &Vec<T>, value: &T) -> bool {
for item in vec {
if item == value {
return true;
}
}
false
}
fn max_emotion(first: usize, second: usize, third: usize) -> String {
if first > second && first > third {
return String::from("😮");
} else if second > third && second > first {
return String::from("🤔");
}
String::from("😐")
}
fn truncate_string_with_condition(ends_of_sentences: &Vec<char>, string: &str) -> String {
let mut index_at = 0;
for c in string.chars() {
if find_in_vector(ends_of_sentences, &c) {
index_at += 1;
}
}
String::from(string.split_at(index_at).1)
}
fn count_sentences_ending_in(terminator: char, string: &str) -> usize {
let mut is_terminating = false;
string
.chars()
.fold(String::new(), |mut acc, c| if c == terminator &&
!is_terminating
{
acc.push(c);
is_terminating = true;
acc
} else if is_terminating && c == terminator {
acc.push(c);
acc
} else {
is_terminating = false;
acc.push(' ');
acc
})
.split_whitespace()
.count()
}
impl TextInfo {
pub fn new(s: &str) -> Self {
let mut alphabets = HashMap::new();
alphabets.insert(
String::from("latin"),
String::from("abcdefghijklmnopqrstuvwxyz"),
);
alphabets.insert(
String::from("cyrillic"),
String::from(
"абвгдежзийклмнопрстуфхцчшщъьюя",
),
);
let ends_of_sentences = vec!['!', '?', '.'];
Self {
text: String::from(s).to_lowercase(),
alphabets: alphabets,
ends_of_sentences: ends_of_sentences,
}
}
pub fn char_count(&self) -> usize {
self.text.chars().count()
}
pub fn alphabetic_count(&self) -> usize {
self.text
.chars()
.filter(|&c| self.is_letter_in_alphabets(c))
.count()
}
pub fn cyrillic_letter_count(&self) -> usize {
self.text
.chars()
.filter(|&c| self.is_in_alphabet("cyrillic", c))
.count()
}
pub fn latin_letter_count(&self) -> usize {
self.text
.chars()
.filter(|&c| self.is_in_alphabet("latin", c))
.count()
}
pub fn word_count(&self) -> usize {
self.text
.chars()
.fold(String::new(), |mut acc, c| if self.is_letter_in_alphabets(
c,
)
{
acc.push(c);
acc
} else {
acc.push(' ');
acc
})
.split_whitespace()
.count()
}
pub fn sentence_count(&self) -> usize {
let trunc = truncate_string_with_condition(&self.ends_of_sentences, &self.text);
trunc
.chars()
.fold(String::new(), |mut acc, c| if find_in_vector(
&self.ends_of_sentences,
&c,
)
{
acc.push(c);
acc
} else {
acc.push(' ');
acc
})
.split_whitespace()
.count()
}
pub fn emotion(&self) -> String {
let trunc = truncate_string_with_condition(&self.ends_of_sentences, &self.text);
let open_mouth = count_sentences_ending_in('!', &trunc);
let thinking_face = count_sentences_ending_in('?', &trunc);
let neutral_face = count_sentences_ending_in('.', &trunc);
let max = max_emotion(open_mouth, thinking_face, neutral_face);
max
}
fn is_letter_in_alphabets(&self, character: char) -> bool {
for (_, alphabet) in &self.alphabets {
if alphabet.find(character).is_some() {
return true;
}
}
false
}
fn is_in_alphabet(&self, alphabet: &str, character: char) -> bool {
match self.alphabets.get(alphabet) {
Some(a) => {
if a.find(character).is_some() {
return true;
}
return false;
}
None => return false,
}
}
}

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

Compiling solution v0.1.0 (file:///tmp/d20171026-5817-1hbbg4r/solution)
invalid expression
!7138 = !DIExpression(6, 34, 0, 6)
invalid expression
!8742 = !DIExpression(6, 34, 8, 6)
invalid expression
!7137 = !DIExpression(6, 34, 0, 6)
invalid expression
!8741 = !DIExpression(6, 34, 8, 6)
    Finished dev [unoptimized + debuginfo] target(s) in 5.27 secs
     Running target/debug/deps/solution-f5dd4e94aa395cae

running 0 tests

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

     Running target/debug/deps/solution_test-c3b431457e2a7a27

running 15 tests
test solution_test::test_alpha_count ... ok
test solution_test::test_alpha_count_2 ... ok
test solution_test::test_char_count ... ok
test solution_test::test_cyrillic_letter_count ... ok
test solution_test::test_emotions ... ok
test solution_test::test_emotions_repeated_punctuation ... FAILED
test solution_test::test_empty_string ... ok
test solution_test::test_latin_letter_count ... ok
test solution_test::test_sentence_count ... ok
test solution_test::test_sentence_count_2 ... FAILED
test solution_test::test_triple_dots_count ... ok
test solution_test::test_unicode_char_count ... ok
test solution_test::test_word_count ... ok
test solution_test::test_word_count_2 ... ok
test solution_test::test_word_count_3 ... ok

failures:

---- solution_test::test_emotions_repeated_punctuation stdout ----
	thread 'solution_test::test_emotions_repeated_punctuation' panicked at 'assertion failed: `(left == right)`
  left: `"🤔"`,
 right: `"😐"`', tests/solution_test.rs:107:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.

---- solution_test::test_sentence_count_2 stdout ----
	thread 'solution_test::test_sentence_count_2' panicked at 'byte index 1 is not a char boundary; it is inside 'д' (bytes 0..2) of `да видим сега: следват ли студентите указания; ще игнорират ли -- тази -- пунктуация?`', src/libcore/str/mod.rs:2188:4


failures:
    solution_test::test_emotions_repeated_punctuation
    solution_test::test_sentence_count_2

test result: FAILED. 13 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out

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

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

Георги качи първо решение на 21.10.2017 23:00 (преди почти 8 години)

Тогава няма да правя suggestions за coding style, докато не решиш, че си го refactor-нал :). Все пак ще те посъветвам освен refactoring, да помислиш и за някои edge cases. Добре ще е да си напишеш малко допълнителни тестове, които да покрият по-особени варианти, и да видиш дали кода ти дава очакваните резултати.

Георги качи решение на 24.10.2017 22:21 (преди почти 8 години)

use std::collections::HashMap;
+use std::vec::Vec;
pub struct TextInfo {
text: String,
alphabets: HashMap<String, String>,
ends_of_sentences: Vec<char>,
}
fn find_in_vector<T: Eq>(vec: &Vec<T>, value: &T) -> bool {
for item in vec {
if item == value {
return true;
}
}
false
}
-fn max_of_three<T: Ord>(first: T, second: T, third: T) -> T {
+fn max_emotion(first: usize, second: usize, third: usize) -> String {
if first > second && first > third {
- return first;
+ return String::from("😮");
} else if second > third && second > first {
- return second;
- } else if third > second && third > first {
- return third;
+ return String::from("🤔");
}
- return third;
+ String::from("😐")
}
+fn truncate_string_with_condition(ends_of_sentences: &Vec<char>, string: &str) -> String {
+ let mut index_at = 0;
+
+ for c in string.chars() {
+ if find_in_vector(ends_of_sentences, &c) {
+ index_at += 1;
+ }
+ }
+
+ String::from(string.split_at(index_at).1)
+}
+
+fn count_sentences_ending_in(terminator: char, string: &str) -> usize {
+ let mut is_terminating = false;
+ string
+ .chars()
+ .fold(String::new(), |mut acc, c| if c == terminator &&
+ !is_terminating
+ {
+ acc.push(c);
+ is_terminating = true;
+ acc
+ } else if is_terminating && c == terminator {
+ acc.push(c);
+ acc
+ } else {
+ is_terminating = false;
+ acc.push(' ');
+ acc
+ })
+ .split_whitespace()
+ .count()
+}
+
impl TextInfo {
pub fn new(s: &str) -> Self {
let mut alphabets = HashMap::new();
alphabets.insert(
String::from("latin"),
String::from("abcdefghijklmnopqrstuvwxyz"),
);
alphabets.insert(
String::from("cyrillic"),
String::from(
"абвгдежзийклмнопрстуфхцчшщъьюя",
),
);
let ends_of_sentences = vec!['!', '?', '.'];
Self {
- text: String::from(s),
+ text: String::from(s).to_lowercase(),
alphabets: alphabets,
ends_of_sentences: ends_of_sentences,
}
}
pub fn char_count(&self) -> usize {
self.text.chars().count()
}
pub fn alphabetic_count(&self) -> usize {
- let mut counter = 0;
- for c in self.text.chars() {
- if self.is_letter_in_alphabets(c) {
- counter += 1
- }
- }
-
- counter
+ self.text
+ .chars()
+ .filter(|&c| self.is_letter_in_alphabets(c))
+ .count()
}
pub fn cyrillic_letter_count(&self) -> usize {
- let mut counter = 0;
- for c in self.text.chars() {
- if self.is_in_alphabet("cyrillic", c) {
- counter += 1
- }
- }
-
- counter
+ self.text
+ .chars()
+ .filter(|&c| self.is_in_alphabet("cyrillic", c))
+ .count()
}
pub fn latin_letter_count(&self) -> usize {
- let mut counter = 0;
- for c in self.text.chars() {
- if self.is_in_alphabet("latin", c) {
- counter += 1
- }
- }
-
- counter
+ self.text
+ .chars()
+ .filter(|&c| self.is_in_alphabet("latin", c))
+ .count()
}
pub fn word_count(&self) -> usize {
- let mut counter = 0;
- let mut new_string = String::new();
- for c in self.text.chars() {
- if self.is_letter_in_alphabets(c) {
- new_string.push(c);
+ self.text
+ .chars()
+ .fold(String::new(), |mut acc, c| if self.is_letter_in_alphabets(
+ c,
+ )
+ {
+ acc.push(c);
+ acc
} else {
- new_string.push(' ');
- }
- }
-
- let mut is_on_word = false;
- let mut is_on_whitespace = false;
-
- for c in new_string.chars() {
- if self.is_letter_in_alphabets(c) && !is_on_word {
- counter += 1;
- is_on_whitespace = false;
- is_on_word = true;
- } else if c == ' ' && !is_on_whitespace {
- is_on_whitespace = true;
- is_on_word = false;
- }
- }
-
- counter
+ acc.push(' ');
+ acc
+ })
+ .split_whitespace()
+ .count()
}
pub fn sentence_count(&self) -> usize {
- let mut counter = 0;
- let mut is_in_sentence = false;
+ let trunc = truncate_string_with_condition(&self.ends_of_sentences, &self.text);
- for c in self.text.chars() {
- if find_in_vector(&self.ends_of_sentences, &c) && is_in_sentence {
- counter += 1;
- is_in_sentence = false;
+ trunc
+ .chars()
+ .fold(String::new(), |mut acc, c| if find_in_vector(
+ &self.ends_of_sentences,
+ &c,
+ )
+ {
+ acc.push(c);
+ acc
} else {
- is_in_sentence = true;
- }
- }
-
- counter
+ acc.push(' ');
+ acc
+ })
+ .split_whitespace()
+ .count()
}
pub fn emotion(&self) -> String {
- let mut open_mouth = 0;
- let mut thinking_face = 0;
- let mut neutral_face = 0;
+ let trunc = truncate_string_with_condition(&self.ends_of_sentences, &self.text);
- let mut is_exclamation = false;
- let mut is_question_mark = false;
- let mut is_dot = false;
+ let open_mouth = count_sentences_ending_in('!', &trunc);
+ let thinking_face = count_sentences_ending_in('?', &trunc);
+ let neutral_face = count_sentences_ending_in('.', &trunc);
- for c in self.text.chars() {
- if c == '!' && !is_exclamation {
- open_mouth += 1;
- is_exclamation = true;
- is_question_mark = false;
- is_dot = false;
- } else if c == ' ' && !is_dot {
- neutral_face += 1;
- is_dot = true;
- is_exclamation = false;
- is_question_mark = false;
- } else if c == '?' && !is_question_mark {
- thinking_face += 1;
- is_question_mark = true;
- is_dot = false;
- is_exclamation = false;
- }
- }
+ let max = max_emotion(open_mouth, thinking_face, neutral_face);
- let max = max_of_three(open_mouth, thinking_face, neutral_face);
- if max == open_mouth {
- return String::from("😮");
- } else if max == thinking_face {
- return String::from("🤔");
- } else {
- return String::from("😐");
- }
+ max
}
fn is_letter_in_alphabets(&self, character: char) -> bool {
for (_, alphabet) in &self.alphabets {
if alphabet.find(character).is_some() {
return true;
}
}
false
}
fn is_in_alphabet(&self, alphabet: &str, character: char) -> bool {
match self.alphabets.get(alphabet) {
Some(a) => {
if a.find(character).is_some() {
return true;
}
return false;
}
None => return false,
}
}
}