Rust AOC 2022第7天在示例上工作,但在正常输入上不工作

bis0qfac  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(80)

链接到AOC:https://adventofcode.com/2022/day/7
我在Rust中做AOC,我被困在第7天。代码可以在示例输入上工作,但不能在普通输入上工作。对于某些上下文,文件树是:

.
├── example_input.txt
├── input.txt
├── src
    ├── bin
    │  └── part_1.rs
    └── lib.rs

input.txt包含以下内容:kfkorulczyk.pl/aoc_d7_input
示例输入如下:

$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k

正常输入的输出应为1501149,但为1035695。
下面是代码:
lib.rs

#![allow(unused)]
use std::borrow::{Borrow, BorrowMut};
use std::cell::RefCell;
use std::fmt;

macro_rules! get_part {
    ($line:expr, $index:expr) => {
        $line.split(" ").nth($index).unwrap()
    };
}

#[derive(Debug)]
pub struct Dir<'a> {
    pub name: &'a str,
    pub files: Vec<File<'a>>,
    pub dirs: Vec<Dir<'a>>,
}

impl<'a> Dir<'a> {
    pub fn add_content_to_subdir(
        &mut self,
        destination_dir: &str,
        new_dir: &'a str,
        new_file: Option<File<'a>>,
    ) -> () {
        let destination_dir = self.find_dir(destination_dir).unwrap();
        match new_file {
            Some(expr) => destination_dir.files.push(expr),
            None => destination_dir.dirs.push(Dir {
                name: new_dir,
                files: Vec::new(),
                dirs: Vec::new(),
            }),
        }
    }

    pub fn find_dir<'b>(&'b mut self, name: &str) -> Option<&'b mut Dir<'a>> {
        if self.name == name {
            return Some(self);
        }
        self.dirs.iter_mut().find_map(|dir| dir.find_dir(name))
    }

    pub fn find_dir_not_mut<'b>(&'b self, name: &str) -> Option<&'b Dir<'a>> {
        if self.name == name {
            return Some(self);
        }

        self.dirs.iter().find_map(|dir| dir.find_dir_not_mut(name))
    }
}

fn calculate_size_of_folder<'a>(dir: &'a RefCell<Dir<'a>>, name: &str) -> Option<i64> {
    let mut sum = 0;
    let search_in = dir.borrow();
    let search_in = search_in.find_dir_not_mut(name).unwrap();
    
    for file in &search_in.files {
        sum += file.size;
    }
    if sum > 100000 {
        return None;
    }
    for subdir in &search_in.dirs {
        if let Some(size) = calculate_size_of_folder(dir, &subdir.name) {
            sum += size;
        }
    }
    if sum > 100000 {
        return None;
    }

    Some(sum)
}


#[derive(Debug)]
pub struct File<'a> {
    pub name: &'a str,
    pub size: i64,
}

fn read_input<'a>(
    input: &'a str,
    dir: &'a RefCell<Dir<'a>>,
) -> (&'a RefCell<Dir<'a>>, Vec<String>) {
    let mut file = File { name: "", size: 13 };
    let mut all_dirs = vec![];
    let mut dir_name = "";
    let mut found_dir = "";
    for line in input.lines() {
        match line {
            line if line.starts_with("$ ls") => {}
            line if line.starts_with("$ cd ..") => {}
            line if line.starts_with("$ cd ") => {
                dir_name = get_part!(line, 2);
                all_dirs.push(dir_name.to_string());
            }
            line if line.starts_with("dir ") => {
                found_dir = get_part!(line, 1);
                dir.borrow_mut()
                    .add_content_to_subdir(dir_name, found_dir, None);
            }
            _ => {
                let size: i64 = get_part!(line, 0).parse::<i64>().unwrap();
                let size: i64 = get_part!(line, 0).parse::<i64>().unwrap();
                let name = get_part!(line, 1);
                dir.borrow_mut().add_content_to_subdir(
                    dir_name,
                    "",
                    Some(File { size, name }),
                );
            }
        }
    }
    (dir, all_dirs)
}

pub fn part_one(input: &str) {
    let mut dir = RefCell::new(Dir {
        name: "/",
        files: vec![],
        dirs: vec![],
    });

    let (file_tree, mut all_dirs) = read_input(&input, &dir);

    let mut sum = 0;

    for dir in &all_dirs {
        let dir_size = calculate_size_of_folder(file_tree, &dir);
        match dir_size {
            Some(expr) => sum += expr,
            None => (),
        }
    }

    println!("{}", sum);
}

第一部分

use d7::*;
use std::fs;

fn main() {
    let input = fs::read_to_string("input.txt").unwrap();
    part_one(input);
}

你可能知道,但cargo install cargo-watchcargo watch -x "run --bin part_1"帮助很大。
我试着重做calculate_size_of_folder函数,但它没有工作。此外,返回calculate_size_of_folder是一个选项,我正在检查大小是否小于100000,因为如果我不这样做,我会得到堆栈溢出错误。

juzqafwq

juzqafwq1#

我在代码中看到的主要bug是忽略了cd ..。这个问题要求你通过一个目录树来建模 * 导航 *;在模拟中的所有点,您的系统都有一个它所占用的“当前目录”。当您看到命令cd ..时,您的系统应该向上移动一级,到父目录,然后从那里继续。

相关问题