added tree generater fkt (unique ids - wiggle) and added another bin tree solution
This commit is contained in:
parent
a0ef259267
commit
007ecbc980
@ -3,4 +3,5 @@ name = "play"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
[dependencies]
|
||||
rand = "0.8"
|
||||
@ -1,4 +1,11 @@
|
||||
use std::{borrow::BorrowMut, cell::RefCell, rc::Rc};
|
||||
use std::{
|
||||
borrow::BorrowMut,
|
||||
cell::RefCell,
|
||||
collections::{btree_map::Range, HashSet},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
use crate::node_struct::TreeNode;
|
||||
|
||||
@ -171,9 +178,7 @@ pub fn test9() -> Option<Rc<RefCell<TreeNode>>> {
|
||||
let mut left_right = TreeNode::new(4);
|
||||
add_child_vals!(left_right, 9, 2);
|
||||
let mut left = TreeNode::new(5);
|
||||
//let mut foor = TreeNode::new(40);
|
||||
add_right_node!(left, left_right);
|
||||
//add_child_nodes!(left, left_right, foor);
|
||||
let mut root = TreeNode::new(1);
|
||||
|
||||
add_child_nodes!(root, left, right);
|
||||
@ -258,3 +263,49 @@ pub fn test_complete_six_nodes() -> Option<Rc<RefCell<TreeNode>>> {
|
||||
add_child_nodes!(root, left, right);
|
||||
wrap!(root)
|
||||
}
|
||||
|
||||
pub fn test12() -> Option<Rc<RefCell<TreeNode>>> {
|
||||
let mut l = TreeNode::new(1);
|
||||
add_left_val!(l, 3);
|
||||
|
||||
let mut r = TreeNode::new(2);
|
||||
add_child_vals!(r, 6, 4);
|
||||
|
||||
let mut root = TreeNode::new(5);
|
||||
add_child_nodes!(root, l, r);
|
||||
|
||||
some_node!(root)
|
||||
}
|
||||
|
||||
/* returns id of last node as well (even though its always count * 11 -> what ever) */
|
||||
pub fn test_big_random_wiggle(count: usize) -> (Option<Rc<RefCell<TreeNode>>>, i32) {
|
||||
let ids = generate_unique_nums(count, 0..count * 10);
|
||||
let mut node = TreeNode::new((11 * count) as i32);
|
||||
for (j, i) in ids.iter().enumerate() {
|
||||
let mut new_node = TreeNode::new(*i as i32);
|
||||
match j % 2 {
|
||||
0 => {
|
||||
add_left_node!(new_node, node);
|
||||
}
|
||||
1 => {
|
||||
add_right_node!(new_node, node);
|
||||
}
|
||||
_ => panic!("what?"),
|
||||
}
|
||||
|
||||
node = new_node;
|
||||
}
|
||||
|
||||
(some_node!(node), (count * 11) as i32)
|
||||
}
|
||||
|
||||
/* helper */
|
||||
fn generate_unique_nums(count: usize, range: std::ops::Range<usize>) -> Vec<usize> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut nums = HashSet::new();
|
||||
|
||||
while nums.len() < count {
|
||||
nums.insert(rng.gen_range(range.clone()));
|
||||
}
|
||||
nums.into_iter().collect()
|
||||
}
|
||||
|
||||
219
src/tree_nodes/2096nodeWalk.rs
Normal file
219
src/tree_nodes/2096nodeWalk.rs
Normal file
@ -0,0 +1,219 @@
|
||||
/* v1 -> prob overflow */
|
||||
|
||||
pub fn get_directions(
|
||||
root: Option<Rc<RefCell<TreeNode>>>,
|
||||
start_value: i32,
|
||||
dest_value: i32,
|
||||
) -> String {
|
||||
let roadmap = create_way_map(root, start_value, dest_value);
|
||||
let (start_road, dest_road) = trim_same_start(
|
||||
roadmap.get(&start_value).unwrap(),
|
||||
roadmap.get(&dest_value).unwrap(),
|
||||
);
|
||||
println!("start up: {:?} , dest down {:?}", start_road, dest_road);
|
||||
|
||||
println!(
|
||||
"start {:?}",
|
||||
start_road
|
||||
.iter()
|
||||
.map(|_| 'U')
|
||||
.chain(dest_road.iter().map(|x| if *x { 'R' } else { 'L' }))
|
||||
.collect::<String>()
|
||||
);
|
||||
start_road
|
||||
.iter()
|
||||
.map(|_| 'U')
|
||||
.chain(dest_road.iter().map(|x| if *x { 'R' } else { 'L' }))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn trim_same_start<'a>(
|
||||
road_to_start: &'a [bool],
|
||||
road_to_end: &'a [bool],
|
||||
) -> (&'a [bool], &'a [bool]) {
|
||||
let mut i = 0;
|
||||
while i < road_to_end.len() && i < road_to_start.len() && road_to_end[i] == road_to_start[i] {
|
||||
i += 1;
|
||||
}
|
||||
(&road_to_start[i..], &road_to_end[i..])
|
||||
}
|
||||
|
||||
pub fn create_way_map(
|
||||
root: Option<Rc<RefCell<TreeNode>>>,
|
||||
start: i32,
|
||||
dest: i32,
|
||||
) -> HashMap<i32, Vec<bool>> {
|
||||
let mut road_map = HashMap::new();
|
||||
let mut nodes_to_check = VecDeque::new();
|
||||
let Some(root_node) = root else {
|
||||
return HashMap::new();
|
||||
};
|
||||
let mut start_found = root_node.borrow().val == start;
|
||||
let mut end_found = root_node.borrow().val == dest;
|
||||
road_map.insert(root_node.borrow().val, Vec::new());
|
||||
nodes_to_check.push_front(root_node);
|
||||
|
||||
while (nodes_to_check.len() > 0) && !(start_found && end_found) {
|
||||
let node = nodes_to_check.pop_back().unwrap();
|
||||
let node_id = node.borrow().val;
|
||||
|
||||
if node.borrow().left.is_some() {
|
||||
let left_node = node.borrow().left.clone().unwrap();
|
||||
let left_id = left_node.borrow().val;
|
||||
start_found = start_found || left_id == start;
|
||||
end_found = end_found || left_id == dest;
|
||||
|
||||
let mut road_to_left = road_map.get(&node_id).unwrap().clone();
|
||||
road_to_left.push(false);
|
||||
road_map.insert(left_id, road_to_left);
|
||||
nodes_to_check.push_front(left_node);
|
||||
}
|
||||
|
||||
if node.borrow().right.is_some() {
|
||||
let right_node = node.borrow().right.clone().unwrap();
|
||||
let right_id = right_node.borrow().val;
|
||||
start_found = start_found || right_id == start;
|
||||
end_found = end_found || right_id == dest;
|
||||
|
||||
let mut road_to_right = road_map.get(&node_id).unwrap().clone();
|
||||
road_to_right.push(true);
|
||||
road_map.insert(right_id, road_to_right);
|
||||
nodes_to_check.push_front(right_node);
|
||||
}
|
||||
}
|
||||
road_map
|
||||
}
|
||||
|
||||
/* uglier but uses far less space and solved the challende TODO: insert fkt */
|
||||
/* Idea: remove all paths from map that are note needed anymore i.e. use path to create child path and insert again only if this is start or end */
|
||||
/* might be overengineered but use match to reduce vec cloning */
|
||||
|
||||
pub fn create_way_map(
|
||||
root: Option<Rc<RefCell<TreeNode>>>,
|
||||
start: i32,
|
||||
dest: i32,
|
||||
) -> HashMap<i32, Vec<bool>> {
|
||||
let mut road_map = HashMap::new();
|
||||
let mut nodes_to_check = VecDeque::new();
|
||||
let Some(root_node) = root else {
|
||||
return HashMap::new();
|
||||
};
|
||||
let mut start_found = root_node.borrow().val == start;
|
||||
let mut end_found = root_node.borrow().val == dest;
|
||||
road_map.insert(root_node.borrow().val, Vec::new());
|
||||
nodes_to_check.push_front(root_node);
|
||||
|
||||
while (nodes_to_check.len() > 0) && !(start_found && end_found) {
|
||||
let node = nodes_to_check.pop_back().unwrap();
|
||||
let node_id = node.borrow().val;
|
||||
let road_to_node = road_map.remove(&node_id).unwrap();
|
||||
|
||||
/* to reduce unneccessary copying */
|
||||
let has_left = node.borrow().left.is_some();
|
||||
let has_right = node.borrow().right.is_some();
|
||||
let is_relevant = node.borrow().val == start || node.borrow().val == dest;
|
||||
match (has_left, has_right, is_relevant) {
|
||||
(true, false, false) => {
|
||||
let left_node = node.borrow().left.clone().unwrap();
|
||||
let left_id = left_node.borrow().val;
|
||||
start_found = start_found || left_id == start;
|
||||
end_found = end_found || left_id == dest;
|
||||
|
||||
let mut road_to_left = road_to_node;
|
||||
road_to_left.push(false);
|
||||
road_map.insert(left_id, road_to_left);
|
||||
nodes_to_check.push_front(left_node);
|
||||
}
|
||||
(false, true, false) => {
|
||||
let right_node = node.borrow().right.clone().unwrap();
|
||||
let right_id = right_node.borrow().val;
|
||||
start_found = start_found || right_id == start;
|
||||
end_found = end_found || right_id == dest;
|
||||
|
||||
let mut road_to_right = road_to_node;
|
||||
road_to_right.push(true);
|
||||
road_map.insert(right_id, road_to_right);
|
||||
nodes_to_check.push_front(right_node);
|
||||
}
|
||||
(false, false, true) => {
|
||||
road_map.insert(node_id, road_to_node);
|
||||
}
|
||||
(true, true, false) => {
|
||||
/* left w/ clone */
|
||||
let left_node = node.borrow().left.clone().unwrap();
|
||||
let left_id = left_node.borrow().val;
|
||||
start_found = start_found || left_id == start;
|
||||
end_found = end_found || left_id == dest;
|
||||
|
||||
let mut road_to_left = road_to_node.clone();
|
||||
road_to_left.push(false);
|
||||
road_map.insert(left_id, road_to_left);
|
||||
nodes_to_check.push_front(left_node);
|
||||
|
||||
/* right w/o clone */
|
||||
let right_node = node.borrow().right.clone().unwrap();
|
||||
let right_id = right_node.borrow().val;
|
||||
start_found = start_found || right_id == start;
|
||||
end_found = end_found || right_id == dest;
|
||||
|
||||
let mut road_to_right = road_to_node;
|
||||
road_to_right.push(true);
|
||||
road_map.insert(right_id, road_to_right);
|
||||
nodes_to_check.push_front(right_node);
|
||||
}
|
||||
(true, false, true) => {
|
||||
let left_node = node.borrow().left.clone().unwrap();
|
||||
let left_id = left_node.borrow().val;
|
||||
start_found = start_found || left_id == start;
|
||||
end_found = end_found || left_id == dest;
|
||||
|
||||
let mut road_to_left = road_to_node.clone();
|
||||
road_to_left.push(false);
|
||||
road_map.insert(left_id, road_to_left);
|
||||
nodes_to_check.push_front(left_node);
|
||||
|
||||
road_map.insert(node_id, road_to_node);
|
||||
}
|
||||
(false, true, true) => {
|
||||
let right_node = node.borrow().right.clone().unwrap();
|
||||
let right_id = right_node.borrow().val;
|
||||
start_found = start_found || right_id == start;
|
||||
end_found = end_found || right_id == dest;
|
||||
|
||||
let mut road_to_right = road_to_node.clone();
|
||||
road_to_right.push(true);
|
||||
road_map.insert(right_id, road_to_right);
|
||||
nodes_to_check.push_front(right_node);
|
||||
|
||||
road_map.insert(node_id, road_to_node);
|
||||
}
|
||||
(true, true, true) => {
|
||||
/* left w/ clone */
|
||||
let left_node = node.borrow().left.clone().unwrap();
|
||||
let left_id = left_node.borrow().val;
|
||||
start_found = start_found || left_id == start;
|
||||
end_found = end_found || left_id == dest;
|
||||
|
||||
let mut road_to_left = road_to_node.clone();
|
||||
road_to_left.push(false);
|
||||
road_map.insert(left_id, road_to_left);
|
||||
nodes_to_check.push_front(left_node);
|
||||
|
||||
/* right w/ clone */
|
||||
let right_node = node.borrow().right.clone().unwrap();
|
||||
let right_id = right_node.borrow().val;
|
||||
start_found = start_found || right_id == start;
|
||||
end_found = end_found || right_id == dest;
|
||||
|
||||
let mut road_to_right = road_to_node.clone();
|
||||
road_to_right.push(true);
|
||||
road_map.insert(right_id, road_to_right);
|
||||
nodes_to_check.push_front(right_node);
|
||||
|
||||
road_map.insert(node_id, road_to_node);
|
||||
}
|
||||
(false, false, false) => {}
|
||||
}
|
||||
}
|
||||
road_map
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user