3 个不稳定版本
0.2.0 | 2022年4月17日 |
---|---|
0.1.1 | 2022年4月17日 |
0.1.0 | 2021年5月8日 |
#729 在 Rust 模式
25KB
110 代码行
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!
声明宏,它非常简单。它的主要目的是掩盖对 自动引用特殊化 的使用。
请参阅 示例 以获取更多演示。
这是如何使用常量泛型的?
因为 Solution
和 ParseInput
特性是对 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;
}
Solution
和 ParseInput
也对 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.0 或 MIT 许可证 许可。除非您明确声明,否则您提交给 advent_of_code_traits 的任何有意贡献,根据 Apache-2.0 许可证定义,将按上述方式双许可,没有任何额外的条款或条件。