Решение на Форматиране на импорти от Ясен Узунов

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

Към профила на Ясен Узунов

Резултати

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

Код

#[cfg(test)]
mod test;
#[derive(Clone)]
pub struct Import<'a>(pub &'a [&'a str]);
pub enum Order {
Original,
Sorted,
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
let mut result: Vec<String> = Vec::new();
for import in imports {
let path = import.0.join("::");
if !result.contains(&path) {
result.push(path);
}
}
if matches!(order, Order::Sorted) {
result.sort();
}
result
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
let mut tree = Tree::new();
for import in imports {
tree.insert(&import);
}
tree.clean_tree();
if matches!(order, Order::Sorted) {
tree.sort_tree();
}
tree.nested_paths()
}
struct Tree { root: Node }
struct Node { value: String, children: Vec<Node> }
impl Tree {
fn new() -> Self {
Tree { root: Node { value: String::new(), children: Vec::new() } }
}
fn insert(&mut self, import: &Import) {
let mut current = &mut self.root;
for (i, &part) in import.0.iter().enumerate() {
let part_str = part.to_string();
let existing_child_index = current.children.iter()
.position(|n| n.value == part_str);
match existing_child_index {
Some(index) => {
current = &mut current.children[index];
}
None => {
let new_node = Node { value: part_str, children: Vec::new() };
current.children.push(new_node);
current = current.children.last_mut().unwrap();
}
}
if i == import.0.len() - 1 {
if current.children.iter().all(|n| n.value != "self") {
current.children.insert(0, Node { value: "self".to_string(), children: Vec::new() });
}
}
}
}
fn nested_paths(&self) -> Vec<String> {
if self.root.children.is_empty() {
return Vec::new();
}
let mut result = Vec::new();
for child in &self.root.children {
let mut path = self.nested_paths_helper(child, child.value.clone(), 1);
//removes the last comma added and then readds the \n
if path.len() > 0 {
path.truncate(path.len() - 2);
path.push('\n');
}
result.push(path);
}
result
}
fn nested_paths_helper(&self, node: &Node, prefix: String, depth: usize) -> String {
let indent = " ".repeat(depth * 4);
if node.children.is_empty() {
return String::new();
}
let mut content = String::new();
content.push_str(&format!("{}::", prefix));
content.push_str("{\n");
for child in &node.children {
if child.children.is_empty() {
content.push_str(&format!("{}{},\n", indent, child.value));
} else {
let new_prefix = child.value.clone();
let nested = self.nested_paths_helper(child, new_prefix, depth + 1);
content.push_str(&format!("{}{}", indent, nested));
}
}
content.push_str(&format!("{}}},\n", " ".repeat((depth - 1) * 4)));
content
}
fn sort_tree(&mut self) {
self.root.sort_children();
}
fn clean_tree(&mut self) {
self.root.clean_lonely_self();
}
}
impl Node {
fn clean_lonely_self(&mut self) {
if self.children.len() == 1 && self.children[0].value == "self" {
self.children.clear();
}
for child in &mut self.children {
child.clean_lonely_self();
}
}
fn sort_children(&mut self) {
self.children.sort_by_key(|a| a.value.clone()); //sorts lexicographically
if let Some(self_idx) = self.children.iter().position(|x| x.value == "self") {
let self_node = self.children.remove(self_idx);
self.children.insert(0, self_node);
}
for child in &mut self.children {
child.sort_children();
}
}
}

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

Compiling solution v0.1.0 (/tmp/d20241203-1739405-1u2fqug/solution)
    Finished test [unoptimized + debuginfo] target(s) in 1.10s
     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_duplicates ... ok
test solution_test::test_flat_original ... 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_only_crate ... FAILED
test solution_test::test_nested_original ... ok
test solution_test::test_nested_original_2 ... ok
test solution_test::test_nested_original_duplicates ... ok
test solution_test::test_nested_original_multi_crate ... ok
test solution_test::test_nested_original_self ... ok
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 ... ok

failures:

---- solution_test::test_nested_only_crate stdout ----
thread 'solution_test::test_nested_only_crate' panicked at 'assertion failed: `(left == right)`
  left: `[""]`,
 right: `["my_crate\n"]`', tests/solution_test.rs:132:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    solution_test::test_nested_only_crate

test result: FAILED. 19 passed; 1 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 15:15 (преди 9 месеца)

Ясен качи решение на 03.12.2024 15:31 (преди 9 месеца)

#[cfg(test)]
mod test;
#[derive(Clone)]
pub struct Import<'a>(pub &'a [&'a str]);
pub enum Order {
Original,
Sorted,
}
pub fn format_flat(imports: &[Import], order: Order) -> Vec<String> {
let mut result: Vec<String> = Vec::new();
for import in imports {
let path = import.0.join("::");
if !result.contains(&path) {
result.push(path);
}
}
if matches!(order, Order::Sorted) {
result.sort();
}
result
}
pub fn format_nested(imports: &[Import], order: Order) -> Vec<String> {
let mut tree = Tree::new();
for import in imports {
tree.insert(&import);
}
tree.clean_tree();
if matches!(order, Order::Sorted) {
tree.sort_tree();
}
tree.nested_paths()
}
struct Tree { root: Node }
struct Node { value: String, children: Vec<Node> }
impl Tree {
fn new() -> Self {
Tree { root: Node { value: String::new(), children: Vec::new() } }
}
fn insert(&mut self, import: &Import) {
let mut current = &mut self.root;
for (i, &part) in import.0.iter().enumerate() {
let part_str = part.to_string();
let existing_child_index = current.children.iter()
.position(|n| n.value == part_str);
match existing_child_index {
Some(index) => {
current = &mut current.children[index];
}
None => {
let new_node = Node { value: part_str, children: Vec::new() };
current.children.push(new_node);
current = current.children.last_mut().unwrap();
}
}
if i == import.0.len() - 1 {
if current.children.iter().all(|n| n.value != "self") {
current.children.insert(0, Node { value: "self".to_string(), children: Vec::new() });
}
}
}
}
fn nested_paths(&self) -> Vec<String> {
if self.root.children.is_empty() {
return Vec::new();
}
let mut result = Vec::new();
for child in &self.root.children {
let mut path = self.nested_paths_helper(child, child.value.clone(), 1);
//removes the last comma added and then readds the \n
- path.truncate(path.len() - 2);
- path.push('\n');
+ if path.len() > 0 {
+ path.truncate(path.len() - 2);
+ path.push('\n');
+ }
result.push(path);
}
result
}
fn nested_paths_helper(&self, node: &Node, prefix: String, depth: usize) -> String {
let indent = " ".repeat(depth * 4);
if node.children.is_empty() {
return String::new();
}
let mut content = String::new();
content.push_str(&format!("{}::", prefix));
content.push_str("{\n");
for child in &node.children {
if child.children.is_empty() {
content.push_str(&format!("{}{},\n", indent, child.value));
} else {
let new_prefix = child.value.clone();
let nested = self.nested_paths_helper(child, new_prefix, depth + 1);
content.push_str(&format!("{}{}", indent, nested));
}
}
content.push_str(&format!("{}}},\n", " ".repeat((depth - 1) * 4)));
content
}
fn sort_tree(&mut self) {
self.root.sort_children();
}
fn clean_tree(&mut self) {
self.root.clean_lonely_self();
}
}
impl Node {
fn clean_lonely_self(&mut self) {
if self.children.len() == 1 && self.children[0].value == "self" {
self.children.clear();
}
for child in &mut self.children {
child.clean_lonely_self();
}
}
fn sort_children(&mut self) {
self.children.sort_by_key(|a| a.value.clone()); //sorts lexicographically
if let Some(self_idx) = self.children.iter().position(|x| x.value == "self") {
let self_node = self.children.remove(self_idx);
self.children.insert(0, self_node);
}
for child in &mut self.children {
child.sort_children();
}
}
}