参加2022年Advent of Code

代码仓库:livexia/advent-of-code-2022

链接: Advent of Code 2022

进一步学习

总结

今年自己可以明显感觉到对于路径查找、动态规划的题目更加熟练,虽然期间也有几天的题目花了非常多的时间,但是基本上自己都能够独立完成,看了去年的排名和时间,可以发现好像去年的结果好像稍好看一些,但是去年如果自己几个小时想不出来,我就直接看社区答案了。今年有三天第二部分应该是看了社区的思路,但是今年借鉴的成分远比去年少,更多的还是自己实现。相比于去年,今年对于记忆化搜索认识更加彻底,意识到在何种场景下增加缓存能够加速程序。而对于 DFS 、 BFS 和 DP 去年可能都仅有简单理解,而今年自己则更加的熟练,对于去年不熟练的迭代和递归,今年也可以熟练运用和理解。虽然今年也有不少需要构建树的题目,但是我通过侧面的方法规避了直接构造树结构,所以对于树的构造依旧不熟练,我现在对于 Rc RefCell 和其他一些的智能指针已经有了足够多的认知,但是相关的练习依旧较少,这是后续需要提升的。在性能分析和程序风格上,我使用 cargo flamegraph 对程序性能进行分析,通过分析可以确定程序优化点,确定是否有必要进一步对当前的方法进行优化。使用 cargo clippy 对 rust 代码进行规范和风格检查,虽然在最后几天才开始使用这个工具,但是这个工具的效益已经让我觉得必不可少,所以在最后我也会对今年 AOC 的之前代码都进行 clippy 检查。今年终于在最后一天的 part 2 挤进前 1000 ,明年加油。

Day 25

Day 24

Day 23

Day 22(半手动完成第二部分)

cube

Day 21

Day 20

Day 19 (其他方法的实现?)

Day 18(待补充并查集实现)

Day 17(待补充)

Day 16(待补充)

Day 15

Interval

参考链接:

思路:

两个方法对比

Day 14

Day 13

Day 12

Day 11

Day 10

Day 9

Day 8

Day 7

构造树

  1. 初步构造 Dir
struct Dir {
    name: String,
    sub_dir: HashMap<String, Dir>,
    files: HashMap<String, File>,
    size: Option<usize>,
    parent: Option<Dir>,
}

这时最初的文件夹思路,但是这样的做法存在严重的问题,问题就在于对上层文件夹的访问,如果将文件夹结构视为树,那么也就是子节点需要访问父节点,那么这样的 Dir 是无法满足需求的,虽然也有 parent 但是会导致所有权的问题,一般来说构造树的时候需要使用 Rc<RefCell<Box<T>>> 但是我并不想这样做,太复杂了。所以我参考了 https://rust-leipzig.github.io/architecture/2016/12/20/idiomatic-trees-in-rust/ 中构造树的方法。

  1. 增加 Dirs ,利用 Vec 和节点索引值来构造树结构
struct Dirs {
    dirs: Vec<Dir>,
    next_index: usize,
}
  1. 调整 Dir 为
struct Dir {
    id: usize,
    sub_dir: Vec<usize>,
    table: HashMap<String, usize>,
    files: HashMap<String, usize>,
    parent: usize,
}

这样修改之后既可以实现子节点快速访问父节点,又可以保证树的结构

  1. 构造 File

File 较为简单,只需要包含文件名和大小,可以视为树的叶子节点。可以优化直接优化为 HashMap ,而不需要额外的结构,直接用哈希表存储文件名和大小即可。

struct File {
    name: String,
    size: usize
}

模拟

  1. 首先对输入进行处理
    • 构造栈 pwd 存储档期当前目录的绝对路径
    • cd .. pwd 弹出栈顶
    • cd \ pwd 设为 vec!["/"]
    • cd name pwd 压入 name
    • 对于 ls 命令,需要完成两件事情,
      1. 记录当前路径下所有的子目录
      2. 记录当前路径下所有文件的大小和
    • 构造 sub_dirs: HashMap<String, Vec<&str>> 来存放每一个路径对应的子目录
    • 构造 sizes: HashMap<String, usize> 存放每一个路径的大小
    • 对输入进行处理时,是没法直接计算出文件夹大小的,读取当前文件夹时子文件夹的情况还没读取和处理,所以输入处理时只能计算出一部分的文件夹大小(文件部分)
  2. 当已经完成所有文件结构的确定,即完成输入同时也完成构造 sub_dirs
    • 从根目录计算每一个文件夹的大小
    • 如果当前目录没有任何子文件夹,那么输入时计算的所有子文件大小总和即是当前文件夹的大小,不更新 sizes
    • 如果当前目录存在子文件夹,那么递归计算子文件夹的大小,确定所有子文件夹大小后,更新 sizes

Day 6

Day 5

Day 4

Day 3

Day 2

Day 1