Advertisement
Guest User

Rust Day 12

a guest
Dec 12th, 2021
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.57 KB | None | 0 0
  1. use std::collections::HashSet;
  2. use std::time::Instant;
  3. use std::fs::read_to_string;
  4.  
  5. fn main() {
  6.     let now = Instant::now();
  7.     day12_2fast2();
  8.     println!("{}", now.elapsed().as_millis());
  9. }
  10.  
  11. //FASTEST DAY 12 implementation
  12. fn day12_2fast2(){
  13.     let input = read_to_string("temp12").expect("AA");
  14.     let paths : Vec<_> = input.lines().map(|x| x.split_once('-').expect("OK")).collect();
  15.     //println!("{:?}", paths);
  16.     let mut walks = walk_path2fast2("start", &paths, "".to_string(), true);
  17.     let mut set = HashSet::new();
  18.     set.extend(walks.iter());
  19.     println!("{}", set.len());
  20. }
  21.  
  22. fn walk_path2fast2(curr_node : &str, paths : &Vec<(&str, &str)>, path_so_far : String, can_double_dip: bool) -> Vec<String> {
  23.     let mut ret = Vec::new();
  24.     if curr_node.eq("end")
  25.     {
  26.         ret.push(path_so_far);
  27.         return ret;
  28.     }
  29.     let is_lower = curr_node.chars().next().expect("").is_lowercase();
  30.     let so_far = path_so_far.to_owned() + "," + curr_node;
  31.     for &path in paths {
  32.         let other_node;
  33.         if path.0.eq(curr_node){
  34.             other_node = path.1
  35.         }
  36.         else if  path.1.eq(curr_node) {
  37.             other_node = path.0;
  38.         }
  39.         else {
  40.             continue;
  41.         }
  42.         if (is_lower && !can_double_dip ) || curr_node.eq("start")
  43.         {
  44.             //remove all paths to this node so we cant go back
  45.             let new_paths: Vec<(&str, &str)> = paths.clone().into_iter().filter(|&x| {
  46.                 if x.0.eq(curr_node) || x.1.eq(curr_node)
  47.                 {
  48.                     return false;
  49.                 }
  50.                 return true;
  51.             }).collect();
  52.  
  53.             ret.extend(walk_path2fast2(other_node, &new_paths, so_far.to_string(), can_double_dip ));
  54.         }
  55.         else if is_lower && can_double_dip {
  56.             //try a double dip
  57.             ret.extend(walk_path2fast2(other_node, paths, so_far.to_string(), false));
  58.             //remove all paths to this node so we cant go back, and we can still double dip later.
  59.             let new_paths: Vec<(&str, &str)> = paths.clone().into_iter().filter(|&x| {
  60.                 if x.0.eq(curr_node) || x.1.eq(curr_node)
  61.                 {
  62.                     return false;
  63.                 }
  64.                 return true;
  65.             }).collect();
  66.             ret.extend(walk_path2fast2(other_node, &new_paths, so_far.to_string(), true));
  67.         }
  68.         // big node we dont care.
  69.         else  {
  70.             ret.extend(walk_path2fast2(other_node, paths, so_far.to_string(), can_double_dip ))
  71.         }
  72.     }
  73.     return ret;
  74. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement