Решение на Форматиране на импорти от Габриела Димитрова
Към профила на Габриела Димитрова
Резултати
- 17 точки от тестове
- 2 бонус точки
- 19 точки общо
- 17 успешни тест(а)
- 3 неуспешни тест(а)
Код
use std::cmp::PartialEq;
use std::collections::HashSet;
pub struct Import<'a>(pub &'a [&'a str]);
impl<'a> PartialEq for Import<'a> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<'a> Eq for Import<'a> {}
impl<'a> Clone for Import<'a> {
fn clone(&self) -> Self {
Import(self.0)
}
}
impl<'a> From<Import<'a>> for String {
fn from(import: Import<'a>) -> Self {
import.0.join("::")
}
}
fn remove_dup(items: Vec<Import>) -> Vec<Import> {
let mut hs = HashSet::new();
let mut res = Vec::new();
for item in items {
if hs.insert(item.0) {
res.push(item);
}
}
res
}
#[derive(PartialEq)]
pub enum Order {
Original,
Sorted,
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
if order == Order::Original {
let items = imports.to_vec();
let res = remove_dup(items);
res.iter().map(|import| String::from(import.clone())).collect()
} else {
let items = imports.to_vec();
let mut res: Vec<String> = remove_dup(items).iter().map(|import|
String::from(import.clone())).collect();
res.sort();
res
}
}
struct RootTree {
root: Node,
}
#[derive(Debug)]
struct Node {
value: String,
children: Vec<Node>,
}
impl RootTree {
// fn new(import: Import) -> Self {
// let mut iter = import.0.into_iter();
// let root_value = iter.next().expect("Import is empty");
// let mut tree = Tree {
// root: Node::new(String::from(root_value)),
// };
// tree.root.insert(&iter.collect::<Vec<_>>());
// tree
// }
fn insert(&mut self, import: &Import) {
self.root.insert(import.0);
}
fn dfs(&self) -> Vec<String> {
let mut vec: Vec<String> = Vec::new();
let mut str: String = String::from("");
for node in self.root.children.iter() {
node.dfs(0, &mut str);
vec.push(str);
str = String::from("");
}
// self.root.dfs(0, &mut vec);
vec
}
fn sort(&mut self) {
for node in self.root.children.iter_mut() {
node.sort();
}
}
}
impl Node {
fn new(value: String) -> Self {
Node {
value,
children: Vec::new(),
}
}
fn dfs(&self, depth: usize, str: &mut String) {
let mut line: String = String::from("");
for _ in 0..depth {
print!(" ");
line.push_str(" ");
}
if self.children.is_empty() {
println!("{},", self.value);
line.push_str(&self.value.to_string());
line.push_str(",\n");
str.push_str(&line);
// vec.push(line);
} else {
//if (depth > 0) {
println!("{}::{{", self.value);
line.push_str(&self.value.to_string());
line.push_str("::{\n");
// str.push_str(line);
str.push_str(&line);
//vec.push(line);
//}
for child in &self.children {
child.dfs(depth + 1, str);
}
line = String::from("");
for _ in 0..depth {
print!(" ");
line.push_str(" ");
}
if depth > 0 {
//if (depth > 1) {
line.push_str("},\n");
print!("}},\n");
//}
} else {
line.push_str("}\n");
print!("}}");
}
str.push_str(&line);
}
}
fn insert(&mut self, import: &[&str]) {
self.find_or_insert_child(import);
}
fn find_or_insert_child(&mut self, import: &[&str]) {
if import.is_empty() {
return;
}
for node in self.children.iter_mut() {
if node.value == import[0] {
return node.find_or_insert_child(&import[1..]);
}
}
self.children.push(Node::new(String::from(import[0])));
self.children.last_mut().unwrap().find_or_insert_child(&import[1..])
}
fn sort(&mut self) {
// println!("{:?}", self.children);
self.children.sort_by(|a, b| { a.value.cmp(&b.value) });
// println!("{:?}", self.children);
for child in self.children.iter_mut() {
child.sort();
}
}
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
let mut trie = RootTree { root: Node::new(String::from("ROOT")) };
for import in imports {
trie.insert(import);
}
if order == Order::Sorted {
trie.sort();
}
trie.dfs()
}
#[cfg(test)]
mod tests {
use super::*; //
#[test]
fn test_basic() {
let imports = &[
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "c"]),
];
assert_eq!(
format_flat(imports, Order::Sorted),
&[
"my_crate::a",
"my_crate::b::B1",
"my_crate::b::B2",
"my_crate::c",
]
);
assert_eq!(
format_nested(imports, Order::Sorted),
&[
concat!(
"my_crate::{\n",
" a,\n",
" b::{\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
"}\n",
)
]
);
}
#[test]
fn test_import_eq() {
let import1 = Import(&["my_crate", "a"]);
let import2 = Import(&["my_crate", "a"]);
let import3 = Import(&["my_crate", "b"]);
let import4 = Import(&["my_crate", "a", "b"]);
assert!(import1 == import2);
assert!(import1 != import3);
assert!(import1 != import4);
assert!(import2 != import3);
assert!(import3 != import4);
}
#[test]
fn test_remove_dup() {
let imports = vec![
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "c"]),
Import(&["my_crate", "a"]),
];
let dedup = vec![
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "c"]),
];
assert!(remove_dup(imports) == dedup);
}
#[test]
fn test_flat() {
let imports = vec![
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "b", "A1"]),
Import(&["my_crate", "d"]),
Import(&["my_crate", "c"]),
];
let sorted = vec![String::from("my_crate::a"),
String::from("my_crate::b::A1"), String::from("my_crate::b::B1"),
String::from("my_crate::b::B2"), String::from("my_crate::c"),
String::from("my_crate::d")];
let original = vec![String::from("my_crate::a"),
String::from("my_crate::b::B1"), String::from("my_crate::b::B2"),
String::from("my_crate::b::A1"), String::from("my_crate::d"),
String::from("my_crate::c")];
let mut strings = format_flat(&imports, Order::Sorted);
assert_eq!(strings, sorted);
strings = format_flat(&imports, Order::Original);
assert_eq!(strings, original);
}
#[test]
fn test_flat_duplicate() {
let imports = &[
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "c"]),
Import(&["my_crate", "b"]),
Import(&["my_crate", "a"]),
];
assert_eq!(
format_flat(imports, Order::Original),
&[
"my_crate::a",
"my_crate::b::B1",
"my_crate::b::B2",
"my_crate::c",
"my_crate::b",
]
);
}
#[test]
fn test_flat_cyrillic() {
let imports = &[
Import(&["my_крате", "ǣ"]),
Import(&["my_crate", "в", "B1"]),
Import(&["my_crate", "г", "B2"]),
];
assert_eq!(
format_flat(imports, Order::Sorted),
&[
"my_crate::в::B1",
"my_crate::г::B2",
"my_крате::ǣ",
]
);
}
// fn test_flat_ordered()
// fn test_flat_sorted()
#[test]
fn test_nested_duplicate() {
let imports = vec![
Import(&["my_crate", "F"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "c"]),
Import(&["my_crate", "F"]),
];
//assert!();
}
#[test]
fn test_nested() {
let imports = &[
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "c"]),
Import(&["my_crate", "F"]),
];
let res = format_nested(imports, Order::Original);
println!("{:?}", res);
// println!();
for line in res {
println!("{}", line);
}
assert_eq!(
format_nested(imports, Order::Original),
&[
concat!(
"my_crate::{\n",
" a,\n",
" b::{\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
" F,\n",
"}\n",
)
]
);
}
#[test]
fn test_nested_sorted() {
let imports = &[
Import(&["crate_A", "b", "B2"]),
Import(&["crate_B", "d"]),
Import(&["crate_B", "c"]),
Import(&["crate_A", "b", "B1"]),
Import(&["crate_A", "a"]),
];
let res = format_nested(imports, Order::Sorted);
println!("{:?}", res);
}
// fn test_nested_self()
// fn test_nested_multi()
// fn test_nested_cyrillic()
}
Лог от изпълнението
Compiling solution v0.1.0 (/tmp/d20241203-1739405-zy0mzk/solution) Finished test [unoptimized + debuginfo] target(s) in 1.47s Running tests/solution_test.rs (target/debug/deps/solution_test-1428e1090729d165) running 20 tests test solution_test::test_flat_empty ... ok test solution_test::test_flat_multi_crate ... ok test solution_test::test_flat_original ... ok test solution_test::test_flat_original_duplicates ... ok test solution_test::test_flat_sorted ... ok test solution_test::test_flat_sorted_duplicates ... ok test solution_test::test_nested_basic ... ok test solution_test::test_nested_deep ... ok test solution_test::test_nested_empty ... ok test solution_test::test_nested_original ... ok test solution_test::test_nested_only_crate ... FAILED test solution_test::test_nested_original_duplicates ... ok test solution_test::test_nested_original_2 ... ok test solution_test::test_nested_original_multi_crate ... ok test solution_test::test_nested_original_self ... FAILED test solution_test::test_nested_sorted ... ok test solution_test::test_nested_sorted_2 ... ok test solution_test::test_nested_sorted_duplicates ... ok test solution_test::test_nested_sorted_multi_crate ... ok test solution_test::test_nested_sorted_self ... FAILED failures: ---- solution_test::test_nested_only_crate stdout ---- my_crate, thread 'solution_test::test_nested_only_crate' panicked at 'assertion failed: `(left == right)` left: `["my_crate,\n"]`, right: `["my_crate\n"]`', tests/solution_test.rs:132:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ---- solution_test::test_nested_original_self stdout ---- my_crate::{ c, b::{ B2, B1, }, a, }thread 'solution_test::test_nested_original_self' panicked at 'assertion failed: `(left == right)` left: `["my_crate::{\n c,\n b::{\n B2,\n B1,\n },\n a,\n}\n"]`, right: `["my_crate::{\n c,\n b::{\n self,\n B2,\n B1,\n },\n a,\n}\n"]`', tests/solution_test.rs:334:5 ---- solution_test::test_nested_sorted_self stdout ---- my_crate::{ a, b::{ B1, B2, }, c, }thread 'solution_test::test_nested_sorted_self' panicked at 'assertion failed: `(left == right)` left: `["my_crate::{\n a,\n b::{\n B1,\n B2,\n },\n c,\n}\n"]`, right: `["my_crate::{\n a,\n b::{\n self,\n B1,\n B2,\n },\n c,\n}\n"]`', tests/solution_test.rs:360:5 failures: solution_test::test_nested_only_crate solution_test::test_nested_original_self solution_test::test_nested_sorted_self test result: FAILED. 17 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s error: test failed, to rerun pass `--test solution_test`
История (2 версии и 0 коментара)
Габриела качи решение на 03.12.2024 17:37 (преди 9 месеца)
use std::cmp::PartialEq;
use std::collections::HashSet;
pub struct Import<'a>(pub &'a [&'a str]);
impl<'a> PartialEq for Import<'a> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<'a> Eq for Import<'a> {}
impl<'a> Clone for Import<'a> {
fn clone(&self) -> Self {
Import(self.0)
}
}
impl<'a> From<Import<'a>> for String {
fn from(import: Import<'a>) -> Self {
import.0.join("::")
}
}
fn remove_dup(items: Vec<Import>) -> Vec<Import> {
let mut hs = HashSet::new();
let mut res = Vec::new();
for item in items {
if hs.insert(item.0) {
res.push(item);
}
}
res
}
#[derive(PartialEq)]
pub enum Order {
Original,
Sorted,
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
if order == Order::Original {
let items = imports.to_vec();
let res = remove_dup(items);
res.iter().map(|import| String::from(import.clone())).collect()
} else {
let items = imports.to_vec();
let mut res: Vec<String> = remove_dup(items).iter().map(|import|
String::from(import.clone())).collect();
res.sort();
res
}
}
struct RootTree {
root: Node,
}
+#[derive(Debug)]
struct Node {
value: String,
children: Vec<Node>,
}
impl RootTree {
// fn new(import: Import) -> Self {
// let mut iter = import.0.into_iter();
// let root_value = iter.next().expect("Import is empty");
// let mut tree = Tree {
// root: Node::new(String::from(root_value)),
// };
// tree.root.insert(&iter.collect::<Vec<_>>());
// tree
// }
fn insert(&mut self, import: &Import) {
self.root.insert(import.0);
}
fn dfs(&self) -> Vec<String> {
let mut vec: Vec<String> = Vec::new();
let mut str: String = String::from("");
for node in self.root.children.iter() {
node.dfs(0, &mut str);
vec.push(str);
str = String::from("");
}
// self.root.dfs(0, &mut vec);
vec
}
-
-
-
+ fn sort(&mut self) {
+ for node in self.root.children.iter_mut() {
+ node.sort();
+ }
+ }
}
impl Node {
fn new(value: String) -> Self {
Node {
value,
children: Vec::new(),
}
}
- fn dfs(&self, depth: usize, mut str: &mut String) {
+ fn dfs(&self, depth: usize, str: &mut String) {
let mut line: String = String::from("");
for _ in 0..depth {
print!(" ");
line.push_str(" ");
}
- if (self.children.is_empty()) {
+ if self.children.is_empty() {
println!("{},", self.value);
line.push_str(&self.value.to_string());
line.push_str(",\n");
str.push_str(&line);
// vec.push(line);
- }
- else {
+ } else {
//if (depth > 0) {
- println!("{}::{{", self.value);
- line.push_str(&self.value.to_string());
- line.push_str("::{\n");
- // str.push_str(line);
- str.push_str(&line);
- //vec.push(line);
+ println!("{}::{{", self.value);
+ line.push_str(&self.value.to_string());
+ line.push_str("::{\n");
+ // str.push_str(line);
+ str.push_str(&line);
+ //vec.push(line);
//}
for child in &self.children {
child.dfs(depth + 1, str);
}
line = String::from("");
for _ in 0..depth {
print!(" ");
line.push_str(" ");
}
- if (depth > 0) {
+ if depth > 0 {
//if (depth > 1) {
- line.push_str("},\n");
- print!("}},\n");
+ line.push_str("},\n");
+ print!("}},\n");
//}
- }
- else {
+ } else {
line.push_str("}\n");
print!("}}");
}
str.push_str(&line);
}
}
fn insert(&mut self, import: &[&str]) {
self.find_or_insert_child(import);
}
fn find_or_insert_child(&mut self, import: &[&str]) {
if import.is_empty() {
- return
+ return;
}
- for mut node in self.children.iter_mut() {
+ for node in self.children.iter_mut() {
if node.value == import[0] {
- return node.find_or_insert_child(&import[1..])
+ return node.find_or_insert_child(&import[1..]);
}
}
self.children.push(Node::new(String::from(import[0])));
self.children.last_mut().unwrap().find_or_insert_child(&import[1..])
}
fn sort(&mut self) {
+ // println!("{:?}", self.children);
self.children.sort_by(|a, b| { a.value.cmp(&b.value) });
+ // println!("{:?}", self.children);
for child in self.children.iter_mut() {
child.sort();
}
}
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
let mut trie = RootTree { root: Node::new(String::from("ROOT")) };
+
for import in imports {
trie.insert(import);
}
- trie.dfs()
+ if order == Order::Sorted {
+ trie.sort();
+ }
-
- // if order == Order::Original {
- // let items = imports.to_vec();
- // } else {
- //
- // }
+ trie.dfs()
}
#[cfg(test)]
mod tests {
use super::*; //
#[test]
fn test_basic() {
let imports = &[
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "c"]),
];
assert_eq!(
format_flat(imports, Order::Sorted),
&[
"my_crate::a",
"my_crate::b::B1",
"my_crate::b::B2",
"my_crate::c",
]
);
assert_eq!(
format_nested(imports, Order::Sorted),
&[
concat!(
"my_crate::{\n",
" a,\n",
" b::{\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
"}\n",
)
]
);
}
#[test]
fn test_import_eq() {
let import1 = Import(&["my_crate", "a"]);
let import2 = Import(&["my_crate", "a"]);
let import3 = Import(&["my_crate", "b"]);
let import4 = Import(&["my_crate", "a", "b"]);
assert!(import1 == import2);
assert!(import1 != import3);
assert!(import1 != import4);
assert!(import2 != import3);
assert!(import3 != import4);
}
#[test]
fn test_remove_dup() {
let imports = vec![
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "c"]),
Import(&["my_crate", "a"]),
];
let dedup = vec![
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "c"]),
];
assert!(remove_dup(imports) == dedup);
}
#[test]
fn test_flat() {
let imports = vec![
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "b", "A1"]),
Import(&["my_crate", "d"]),
Import(&["my_crate", "c"]),
];
let sorted = vec![String::from("my_crate::a"),
String::from("my_crate::b::A1"), String::from("my_crate::b::B1"),
String::from("my_crate::b::B2"), String::from("my_crate::c"),
String::from("my_crate::d")];
let original = vec![String::from("my_crate::a"),
String::from("my_crate::b::B1"), String::from("my_crate::b::B2"),
String::from("my_crate::b::A1"), String::from("my_crate::d"),
String::from("my_crate::c")];
let mut strings = format_flat(&imports, Order::Sorted);
assert_eq!(strings, sorted);
strings = format_flat(&imports, Order::Original);
assert_eq!(strings, original);
}
#[test]
fn test_flat_duplicate() {
let imports = &[
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "c"]),
Import(&["my_crate", "b"]),
Import(&["my_crate", "a"]),
];
assert_eq!(
format_flat(imports, Order::Original),
&[
"my_crate::a",
"my_crate::b::B1",
"my_crate::b::B2",
"my_crate::c",
"my_crate::b",
]
);
}
#[test]
fn test_flat_cyrillic() {
let imports = &[
Import(&["my_крате", "ǣ"]),
Import(&["my_crate", "в", "B1"]),
Import(&["my_crate", "г", "B2"]),
];
assert_eq!(
format_flat(imports, Order::Sorted),
&[
"my_crate::в::B1",
"my_crate::г::B2",
"my_крате::ǣ",
]
);
}
// fn test_flat_ordered()
// fn test_flat_sorted()
#[test]
fn test_nested_duplicate() {
let imports = vec![
Import(&["my_crate", "F"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "c"]),
Import(&["my_crate", "F"]),
];
//assert!();
}
#[test]
fn test_nested() {
let imports = &[
Import(&["my_crate", "a"]),
Import(&["my_crate", "b", "B1"]),
Import(&["my_crate", "b", "B2"]),
Import(&["my_crate", "c"]),
Import(&["my_crate", "F"]),
];
let res = format_nested(imports, Order::Original);
println!("{:?}", res);
- println!();
+ // println!();
for line in res {
println!("{}", line);
}
assert_eq!(
- format_nested(imports, Order::Sorted),
+ format_nested(imports, Order::Original),
&[
concat!(
"my_crate::{\n",
" a,\n",
" b::{\n",
" B1,\n",
" B2,\n",
" },\n",
" c,\n",
" F,\n",
"}\n",
)
]
);
}
#[test]
- fn test_nested_original() {
+ fn test_nested_sorted() {
+ let imports = &[
+ Import(&["crate_A", "b", "B2"]),
+ Import(&["crate_B", "d"]),
+ Import(&["crate_B", "c"]),
+ Import(&["crate_A", "b", "B1"]),
+ Import(&["crate_A", "a"]),
+ ];
+ let res = format_nested(imports, Order::Sorted);
+ println!("{:?}", res);
}
- // fn test_nested_sorted()
+
// fn test_nested_self()
// fn test_nested_multi()
// fn test_nested_cyrillic()
}