#advent #solution #advent-of-code #traits #specialization #const-generics #framework

advent_of_code_traits

Rust 中实现 Advent of Code 解决方案的轻量级、灵活框架

3 个不稳定版本

0.2.0 2022年4月17日
0.1.1 2022年4月17日
0.1.0 2021年5月8日

#729Rust 模式

MIT/Apache

25KB
110 代码行

Build Status Latest Version

impl 解决方案<'_, 第25天,第二部分> for AdventOfCode2021<第25天>

这是什么?

这是 advent_of_code_traits,一套用于在 Rust 中实现 Advent of Code 解决方案的 traits。

它采用基于 traits 的方法,使用 const-generics 和 autoderef 特化。

这基本上是玩 Rust 类型系统的借口。

实验性

这已经可以使用,但随着 traits 的改进和细化,将会出现 频繁的 破坏性更改。计划是在准备就绪时发布稳定版本,时间定在 2021 年 12 月

请参阅 变更日志,以了解当前的进度。

用法

请参阅 示例

用你的解决方案实现 Advent of Code 每天的 traits。

导入工具

use advent_of_code_traits::{days::*, MissingPartTwo, Part1, Part2, ParseInput, run, Solution, SolutionRunner};

为你的结构体实现 Solution

pub struct AdventOfCode2021<const DAY: u32>;

impl Solution<'_, Day25, Part1> for AdventOfCode2021<Day25> {
    type Input = Vec<u32>;
    type Output = u32;
    
    fn solve(&self, input: &Self::Input) -> Self::Output {
        // your solution to Part1 here...
    }
}

这样我们就可以解决给定的类型为 Vec<u32> 的解决方案,但 Advent of Code 给我们的是纯文本输入。

所以首先我们需要解析输入...

为你的结构体实现 ParseInput

// ..continued from above

impl ParseInput<'_, Day25, Part1> for AdventOfCode2021<Day25> {
    type Parsed = Vec<u32>; // <-- the input type fed to Solution::solve

    fn parse_input(&self, input: &'_ str) -> Self::Parsed {
        input
            .lines()
            .map(|s| s.parse().expect("invalid integer"))
            .collect()
    }
}

标记第二部分为缺失

要运行 Advent of Code 一天的第一部分,目前需要实现 MissingPartTwo 来帮助区分特化

impl MissingPartTwo<Day25> for AdventOfCode2021<Day25> {}

如果你不这样做(并且没有为第二部分实现 Solution),你将看到类似以下错误:

the method `run` exists for reference `&&&AdventOfCode2021<25_u32>`, but its trait bounds were not satisfied
the following trait bounds were not satisfied:
`AdventOfCode2021<25_u32>: MissingPartTwo<25_u32>`
which is required by `AdventOfCode2021<25_u32>: SolutionRunner<25_u32, 1_u16>`rustcE0599

从 main.rs 运行

这部分是实际运行我们解决方案的地方!

let input = std::fs::read_to_string("./input/2021/day25.txt").expect("failed to read input");
run!(AdventOfCode2021::<Day25>, &input);

它从文件中读取输入,并将其传递给你的结构体进行解析和解决。它将打印解决方案的输出(必须实现 Debug)。

run! 目前是一个谦逊的 macro_rules! 声明宏,它非常简单。它的主要目的是掩盖对 自动引用特殊化 的使用。

请参阅 示例 以获取更多演示。

这是如何使用常量泛型的?

因为 SolutionParseInput 特性是对 const DAY: u32 泛型的,所以你可以为相同的结构体多次实现它们。如果编译器发现你为相同的 DAY 实现了两次(按照它应有的方式),它只会对你大喊大叫!

在示例中使用了 Day1(因为它在我的看法中看起来很棒)。它很简单,就是 1_u32

advent_of_code_traits::days 看起来是这样的

mod days {
    pub const Day1: u32 = 1;
    pub const Day2: u32 = 2;
    // ...
    pub const Day25: u32 = 25;
}

SolutionParseInput 也对 const PART: u8 泛型,其工作方式与 DAY 非常相似。

这是如何使用特殊化的?

先前的技术

我非常感谢 @gobanos 的 cargo-aoc,在创建这个项目时,它给了我巨大的启发。

这个crate(软件包)在方便性和易用性上无法与 cargo-aoc 相比。

话虽如此,我希望它能为桌面带来一些新东西(也许更快的编译时间?)并且希望其他人使用它时能像我使用 cargo-aoc 一样享受。

我在2021年之前的所有Rust Advent of Codes 都使用了 cargo-aoc,它是对程序宏的疯狂、天才的使用。

感谢 Gobanos! :)

贡献

欢迎贡献,请参阅 CONTRIBUTING

请参阅 ARCHITECTURE 以了解代码库的某种指导性游览。

我可能需要很长时间才能合并/发布你的贡献,我在这方面仍然缺乏经验。不过,我非常感激它们。

感谢所有迄今为止帮助这个项目的人


许可

在您的选择下,根据 Apache License, Version 2.0MIT 许可证 许可。
除非您明确声明,否则您提交给 advent_of_code_traits 的任何有意贡献,根据 Apache-2.0 许可证定义,将按上述方式双许可,没有任何额外的条款或条件。

无运行时依赖