advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git

main.rs (2613B)

    1 use regex::Regex;
    2 use std::collections::HashMap;
    3 use std::path::PathBuf;
    4 
    5 #[derive(Debug)]
    6 enum Node {
    7     Dir,
    8     File { size: usize },
    9 }
   10 
   11 fn main() {
   12     let input = {
   13         let mut tmp = HashMap::new();
   14         let mut root = PathBuf::new();
   15         for l in std::fs::read_to_string("input.txt")
   16             .unwrap()
   17             .trim()
   18             .split('\n')
   19         {
   20             if Regex::new(r"^\$ cd ..$").unwrap().is_match(l) {
   21                 root.pop();
   22             } else if let Some(cap) = Regex::new(r"^\$ cd (?P<dir_name>.*)$").unwrap().captures(l) {
   23                 root.push(cap.name("dir_name").unwrap().as_str());
   24                 tmp.insert(root.clone(), Node::Dir);
   25             } else if let Some(cap) = Regex::new(r"^(?P<size>[0-9]+) (?P<file_name>.*)$")
   26                 .unwrap()
   27                 .captures(l)
   28             {
   29                 root.push(cap.name("file_name").unwrap().as_str());
   30                 tmp.insert(
   31                     root.clone(),
   32                     Node::File {
   33                         size: cap.name("size").unwrap().as_str().parse().unwrap(),
   34                     },
   35                 );
   36                 root.pop();
   37             } else if let Some(cap) = Regex::new(r"^dir (?P<dir_name>.*)$").unwrap().captures(l) {
   38                 root.push(cap.name("dir_name").unwrap().as_str());
   39                 tmp.insert(root.clone(), Node::Dir);
   40                 root.pop();
   41             } else if Regex::new(r"^\$ ls$").unwrap().is_match(l) {
   42             } else {
   43                 unreachable!();
   44             }
   45         }
   46         tmp
   47     };
   48     let dir_sizes = {
   49         let mut tmp = HashMap::new();
   50         for (path, node) in input.iter() {
   51             let mut path = path.clone();
   52             if let Node::File { size } = node {
   53                 while path.pop() {
   54                     tmp.insert(path.clone(), *tmp.get(&path).unwrap_or(&0) + size);
   55                 }
   56             }
   57         }
   58         tmp
   59     };
   60     // 1307902
   61     println!("Part 1: {}", part_1(&dir_sizes, 100000));
   62     // 7068748
   63     println!("Part 2: {}", part_2(&dir_sizes, 70000000, 30000000));
   64 }
   65 
   66 fn part_1(dir_sizes: &HashMap<PathBuf, usize>, size_thresh: usize) -> usize {
   67     dir_sizes
   68         .values()
   69         .filter(|&size| *size <= size_thresh)
   70         .sum()
   71 }
   72 
   73 fn part_2(
   74     dir_sizes: &HashMap<PathBuf, usize>,
   75     tot_space: usize,
   76     required_free_space: usize,
   77 ) -> usize {
   78     let used_space = dir_sizes.get(&PathBuf::from("/")).unwrap();
   79     *dir_sizes
   80         .values()
   81         .filter(|&size| tot_space - used_space + *size >= required_free_space)
   82         .min()
   83         .unwrap()
   84 }