added tree generater fkt (unique ids - wiggle) and added another bin tree solution

This commit is contained in:
hendrik 2024-07-16 20:50:31 +02:00
parent a0ef259267
commit 007ecbc980
3 changed files with 275 additions and 4 deletions

View File

@ -3,4 +3,5 @@ name = "play"
version = "0.1.0"
edition = "2021"
[dependencies]
[dependencies]
rand = "0.8"

View File

@ -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()
}

View 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
}