porting over AOC from previous years to a monorepo.
This commit is contained in:
commit
84c4cf9991
194 changed files with 30104 additions and 0 deletions
1
2022/.gitignore
vendored
Normal file
1
2022/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/target
|
||||
197
2022/Cargo.lock
generated
Normal file
197
2022/Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aoc_libs"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day01"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day02"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day03"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day04"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day05"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day06"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day07"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"regex",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day08"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day09"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aoc_libs",
|
||||
"once_cell",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day10"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aoc_libs",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "template"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aoc_libs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
21
2022/Cargo.toml
Normal file
21
2022/Cargo.toml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"template",
|
||||
"aoc_libs",
|
||||
"days/*",
|
||||
]
|
||||
default-members = [ "days/*", "aoc_libs" ]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
authors = ["Gabriel Venberg"]
|
||||
edition = "2021"
|
||||
description = "advent of code 2022 in rust"
|
||||
|
||||
[workspace.dependencies]
|
||||
aoc_libs = {path = "./aoc_libs"}
|
||||
regex = "1"
|
||||
once_cell = "1.16"
|
||||
thiserror = "1.0"
|
||||
nom = "7.1"
|
||||
6
2022/aoc_libs/Cargo.toml
Normal file
6
2022/aoc_libs/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "aoc_libs"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
description.workspace = true
|
||||
1
2022/aoc_libs/src/lib.rs
Normal file
1
2022/aoc_libs/src/lib.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub mod points;
|
||||
211
2022/aoc_libs/src/points.rs
Normal file
211
2022/aoc_libs/src/points.rs
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
|
||||
pub struct Point {
|
||||
pub x: isize,
|
||||
pub y: isize,
|
||||
}
|
||||
|
||||
impl Point {
|
||||
/// converts a point (representing a point on a 4 quadrant grid with positive xy in the
|
||||
/// top-right) into a upoint (representing a point on a 1 quadrant grid with the origin in the
|
||||
/// top-left corner). Returns none if the resulting point would have either number negative.
|
||||
pub fn to_upoint(self, zero_coord: &UPoint) -> Option<UPoint> {
|
||||
Some(UPoint {
|
||||
x: zero_coord.x.checked_add_signed(self.x)?,
|
||||
y: zero_coord.y.checked_add_signed(-self.y)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Add for Point {
|
||||
type Output = Point;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
x: self.x + rhs.x,
|
||||
y: self.y + rhs.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::AddAssign for Point {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
*self = *self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Sub for Point {
|
||||
type Output = Point;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
x: self.x - rhs.x,
|
||||
y: self.y - rhs.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::SubAssign for Point {
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
*self = *self - rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Neg for Point {
|
||||
type Output = Point;
|
||||
|
||||
fn neg(self) -> Self::Output {
|
||||
Point {
|
||||
x: -self.x,
|
||||
y: -self.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// an unsigned point in 2d space
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct UPoint {
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
}
|
||||
|
||||
impl UPoint {
|
||||
/// converts a upoint (representing a point on a 1 quadrant grid with the origin in the
|
||||
/// top-left corner) into a point( representing a point on a 4 quadrant grid with positive xy
|
||||
/// in the top-right)
|
||||
pub fn to_point(self, zero_coord: &UPoint) -> Point {
|
||||
Point {
|
||||
x: -(zero_coord.x as isize - self.x as isize),
|
||||
y: zero_coord.y as isize - self.y as isize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Add for UPoint {
|
||||
type Output = UPoint;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
x: self.x + rhs.x,
|
||||
y: self.y + rhs.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::AddAssign for UPoint {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
*self = *self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Sub for UPoint {
|
||||
type Output = UPoint;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
x: self.x - rhs.x,
|
||||
y: self.y - rhs.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::SubAssign for UPoint {
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
*self = *self - rhs
|
||||
}
|
||||
}
|
||||
|
||||
/// A matrix that allows negative co-oordinates. Will panic if referencing out of bounds, just like
|
||||
/// a normal 2d array.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct FourQuadrantMatrix<const X: usize, const Y: usize, T> {
|
||||
matrix: [[T; X]; Y],
|
||||
max_point: Point,
|
||||
min_point: Point,
|
||||
zero_coord: UPoint,
|
||||
}
|
||||
|
||||
impl<const X: usize, const Y: usize, T> FourQuadrantMatrix<{ X }, { Y }, T>
|
||||
where
|
||||
T: Copy,
|
||||
T: Default,
|
||||
{
|
||||
/// generates a new FourQuadrantMatrix with a given zero point (the point in the underlying 2d
|
||||
/// array considered to be (0,0))
|
||||
pub fn new(zero_coord: UPoint) -> FourQuadrantMatrix<{ X }, { Y }, T> {
|
||||
FourQuadrantMatrix {
|
||||
matrix: [[T::default(); X]; Y],
|
||||
max_point: UPoint { x: X - 1, y: 0 }.to_point(&zero_coord),
|
||||
min_point: UPoint { x: 0, y: Y - 1 }.to_point(&zero_coord),
|
||||
zero_coord,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn zero_coord(&self) -> UPoint {
|
||||
self.zero_coord
|
||||
}
|
||||
|
||||
pub fn min_point(&self) -> Point {
|
||||
self.min_point
|
||||
}
|
||||
|
||||
pub fn max_point(&self) -> Point {
|
||||
self.max_point
|
||||
}
|
||||
|
||||
/// makes sure a point is in bounds and if not, brings it in bounds.
|
||||
pub fn bound_point(&self, point: &mut Point) {
|
||||
if point.x > self.max_point.x {
|
||||
point.x = self.max_point.x
|
||||
}
|
||||
|
||||
if point.y > self.max_point.y {
|
||||
point.y = self.max_point.y
|
||||
}
|
||||
|
||||
if point.x < self.min_point.x {
|
||||
point.x = self.min_point.x
|
||||
}
|
||||
|
||||
if point.y < self.min_point.y {
|
||||
point.y = self.min_point.y
|
||||
}
|
||||
}
|
||||
|
||||
/// checks if the point is in bounds.
|
||||
pub fn is_in_bounds(&self, point: &Point) -> bool {
|
||||
point.x <= self.max_point.x
|
||||
&& point.y <= self.max_point.y
|
||||
&& point.x >= self.min_point.x
|
||||
&& point.y >= self.min_point.y
|
||||
}
|
||||
/// fills the matrix with the Ts default value.
|
||||
pub fn reset_matrix(&mut self) {
|
||||
self.matrix = [[T::default(); X]; Y];
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const X: usize, const Y: usize> std::ops::IndexMut<Point> for FourQuadrantMatrix<{ X }, { Y }, T> {
|
||||
fn index_mut(&mut self, index: Point) -> &mut Self::Output {
|
||||
let upoint = index
|
||||
.to_upoint(&self.zero_coord)
|
||||
.expect("would result in negative unsigned coordinate!");
|
||||
&mut self.matrix[upoint.y][upoint.x]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const X: usize, const Y: usize> std::ops::Index<Point> for FourQuadrantMatrix<{ X }, { Y }, T> {
|
||||
type Output = T;
|
||||
|
||||
fn index(&self, index: Point) -> &Self::Output {
|
||||
let upoint = index
|
||||
.to_upoint(&self.zero_coord)
|
||||
.expect("would result in negative unsigned coordinate!");
|
||||
&self.matrix[upoint.y][upoint.x]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const X: usize, const Y: usize> From<FourQuadrantMatrix<{ X }, { Y }, T>> for [[T; X]; Y] {
|
||||
fn from(value: FourQuadrantMatrix<{ X }, { Y }, T>) -> Self {
|
||||
value.matrix
|
||||
}
|
||||
}
|
||||
6
2022/days/01/Cargo.toml
Normal file
6
2022/days/01/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "day01"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
2255
2022/days/01/src/input.txt
Normal file
2255
2022/days/01/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
14
2022/days/01/src/main.rs
Normal file
14
2022/days/01/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod parse;
|
||||
mod part1;
|
||||
mod part2;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
let _structured_input = parse::parse(_input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&_structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&_structured_input));
|
||||
}
|
||||
48
2022/days/01/src/parse.rs
Normal file
48
2022/days/01/src/parse.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Elf(pub Vec<usize>);
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Elf> {
|
||||
input
|
||||
.trim()
|
||||
.split("\n\n")
|
||||
.map(|group| {
|
||||
Elf(group
|
||||
.split('\n')
|
||||
.map(|line| line.parse().unwrap())
|
||||
.collect())
|
||||
})
|
||||
.collect::<Vec<Elf>>()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = "1000
|
||||
2000
|
||||
3000
|
||||
|
||||
4000
|
||||
|
||||
5000
|
||||
6000
|
||||
|
||||
7000
|
||||
8000
|
||||
9000
|
||||
|
||||
10000";
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Elf(vec![1000, 2000, 3000]),
|
||||
Elf(vec![4000]),
|
||||
Elf(vec![5000, 6000]),
|
||||
Elf(vec![7000, 8000, 9000]),
|
||||
Elf(vec![10000])
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
27
2022/days/01/src/part1.rs
Normal file
27
2022/days/01/src/part1.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use crate::parse;
|
||||
|
||||
pub fn part1(input: &[parse::Elf]) -> usize {
|
||||
input
|
||||
.iter()
|
||||
.map(|elf| elf.0.iter().sum::<usize>())
|
||||
.max()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
parse::Elf(vec![1000, 2000, 3000]),
|
||||
parse::Elf(vec![4000]),
|
||||
parse::Elf(vec![5000, 6000]),
|
||||
parse::Elf(vec![7000, 8000, 9000]),
|
||||
parse::Elf(vec![10000]),
|
||||
];
|
||||
|
||||
assert_eq!(part1(&input), 24000);
|
||||
}
|
||||
}
|
||||
27
2022/days/01/src/part2.rs
Normal file
27
2022/days/01/src/part2.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use crate::parse;
|
||||
|
||||
pub fn part2(input: &[parse::Elf]) -> usize {
|
||||
let mut input = input
|
||||
.iter()
|
||||
.map(|elf| elf.0.iter().sum::<usize>())
|
||||
.collect::<Vec<usize>>();
|
||||
input.sort_unstable();
|
||||
input[input.len() - 3..].iter().sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = vec![
|
||||
parse::Elf(vec![1000, 2000, 3000]),
|
||||
parse::Elf(vec![4000]),
|
||||
parse::Elf(vec![5000, 6000]),
|
||||
parse::Elf(vec![7000, 8000, 9000]),
|
||||
parse::Elf(vec![10000]),
|
||||
];
|
||||
assert_eq!(part2(&input), 45000);
|
||||
}
|
||||
}
|
||||
6
2022/days/02/Cargo.toml
Normal file
6
2022/days/02/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "day02"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
2500
2022/days/02/src/input.txt
Normal file
2500
2022/days/02/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
13
2022/days/02/src/main.rs
Normal file
13
2022/days/02/src/main.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(_input));
|
||||
}
|
||||
62
2022/days/02/src/part1.rs
Normal file
62
2022/days/02/src/part1.rs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
use crate::utilities::*;
|
||||
pub fn part1(input: &str) -> usize {
|
||||
parse(input).iter().map(calc_score).sum()
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Strategy> {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let elf = match line.as_bytes()[0] {
|
||||
b'A' => Play::Rock,
|
||||
b'B' => Play::Paper,
|
||||
b'C' => Play::Scissors,
|
||||
_ => panic!("your opponent not playing defined strategy!"),
|
||||
};
|
||||
let you = match line.as_bytes()[2] {
|
||||
b'X' => Play::Rock,
|
||||
b'Y' => Play::Paper,
|
||||
b'Z' => Play::Scissors,
|
||||
_ => panic!("you are not playing defined strategy!"),
|
||||
};
|
||||
Strategy { elf, you }
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = "A Y
|
||||
B X
|
||||
C Z";
|
||||
assert_eq!(part1(input), 15);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = "A Y
|
||||
B X
|
||||
C Z";
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Strategy {
|
||||
elf: Play::Rock,
|
||||
you: Play::Paper
|
||||
},
|
||||
Strategy {
|
||||
elf: Play::Paper,
|
||||
you: Play::Rock
|
||||
},
|
||||
Strategy {
|
||||
elf: Play::Scissors,
|
||||
you: Play::Scissors
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
87
2022/days/02/src/part2.rs
Normal file
87
2022/days/02/src/part2.rs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub enum GameResult {
|
||||
Win,
|
||||
Loss,
|
||||
Draw,
|
||||
}
|
||||
|
||||
pub struct ResultStrategy {
|
||||
pub elf: Play,
|
||||
pub you: GameResult,
|
||||
}
|
||||
|
||||
pub fn part2(input: &str) -> usize {
|
||||
parse(input)
|
||||
.iter()
|
||||
.map(gen_strategy)
|
||||
.map(|strat| calc_score(&strat))
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn gen_strategy(input: &ResultStrategy) -> Strategy {
|
||||
match input.you {
|
||||
GameResult::Win => Strategy {
|
||||
elf: input.elf,
|
||||
you: gen_win(input.elf),
|
||||
},
|
||||
GameResult::Draw => Strategy {
|
||||
elf: input.elf,
|
||||
you: input.elf,
|
||||
},
|
||||
GameResult::Loss => Strategy {
|
||||
elf: input.elf,
|
||||
you: gen_loss(input.elf),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_win(opponent: Play) -> Play {
|
||||
match opponent {
|
||||
Play::Rock => Play::Paper,
|
||||
Play::Paper => Play::Scissors,
|
||||
Play::Scissors => Play::Rock,
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_loss(opponent: Play) -> Play {
|
||||
match opponent {
|
||||
Play::Rock => Play::Scissors,
|
||||
Play::Paper => Play::Rock,
|
||||
Play::Scissors => Play::Paper,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> Vec<ResultStrategy> {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let elf = match line.as_bytes()[0] {
|
||||
b'A' => Play::Rock,
|
||||
b'B' => Play::Paper,
|
||||
b'C' => Play::Scissors,
|
||||
_ => panic!("your opponent not playing defined strategy!"),
|
||||
};
|
||||
let you = match line.as_bytes()[2] {
|
||||
b'X' => GameResult::Loss,
|
||||
b'Y' => GameResult::Draw,
|
||||
b'Z' => GameResult::Win,
|
||||
_ => panic!("you are not playing defined strategy!"),
|
||||
};
|
||||
ResultStrategy { elf, you }
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = "A Y
|
||||
B X
|
||||
C Z";
|
||||
assert_eq!(part2(input), 12);
|
||||
}
|
||||
}
|
||||
36
2022/days/02/src/utilities.rs
Normal file
36
2022/days/02/src/utilities.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Play {
|
||||
Rock = 1,
|
||||
Paper = 2,
|
||||
Scissors = 3,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Strategy {
|
||||
pub elf: Play,
|
||||
pub you: Play,
|
||||
}
|
||||
|
||||
pub fn calc_score(input: &Strategy) -> usize {
|
||||
//an enum wins if (you-elf)%3 = 1, looses if it = 2
|
||||
(match (input.you as i8 - input.elf as i8).rem_euclid(3) {
|
||||
1 => 6,
|
||||
2 => 0,
|
||||
0 => 3,
|
||||
_ => unreachable!("you were {}, elf was {}", input.you as i8, input.elf as i8),
|
||||
}) + input.you as usize //play enum has value corresponding to its score.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_calc_score() {
|
||||
let input = Strategy {
|
||||
elf: Play::Scissors,
|
||||
you: Play::Scissors,
|
||||
};
|
||||
assert_eq!(calc_score(&input), 6);
|
||||
}
|
||||
}
|
||||
6
2022/days/03/Cargo.toml
Normal file
6
2022/days/03/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "day03"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
300
2022/days/03/src/input.txt
Normal file
300
2022/days/03/src/input.txt
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
PcPlnShmrLmBnmcwBhrmcmbHNGFGpwdFFwGNjNbGqNHH
|
||||
tzQfRJfWZZztWzVtCTfRzFZjpFjNZjGLHbdHLDdjpb
|
||||
CCQTzRLzvQVVfRzJfMPsnBlglgPmBgPmvSrl
|
||||
RMfvbbszHTsssFPzDQPggpQJPQ
|
||||
NSNcqVtLVGgDlpQBClVB
|
||||
hmStGNNLhjNrpWLGSjWrZssbZTMMvTfMnThbRRTs
|
||||
fTrTPGTbfftWBBmLjrJL
|
||||
DqHwVMqVplDslmlZmpHVwNnShWZFdBBdjWBtWtdtWJSSLS
|
||||
MNslpDvVHlwsmpQRgQgCfTTcvcRQ
|
||||
pBBhRgDsMsswprBhvgRglZtFGFFRqZtZmRtNqtZPPN
|
||||
TdmmzzmdZdqdGFtF
|
||||
nmSccCVmSCpDCswMwl
|
||||
NptqDsQtDTQzCvlzCpRlRp
|
||||
jmZcndmjbZcjrmDvFMFFlwCvzFnF
|
||||
jjgLVLrGcdDBNhWQTgHg
|
||||
mLVhhfSMSTmMwClHGdpjDHjGdV
|
||||
zPrZgJCgbsnrPtZzsCsbpRDjBRHnjGDRldRHppcG
|
||||
JJrbsFrZqrgWbbqbrgWzJPNTwhTNCmmvfWCShhhmwwfm
|
||||
ftgfljvgfgBTNvtggFDDGLGRDnMDzcQzncGt
|
||||
VdbpbVdZwdwrsVVLRrMrDLDBGnBGcM
|
||||
wmpWwWsHWBCCCPPvjvmSqlfTTmSNgN
|
||||
jSqmzmmSSDRjLMLDwqjNcMMLTTflffWCCsRsTHnHVrfHWTsr
|
||||
tdbgZpgBPdgGZGGFTHVpCsCVfVsJpnWl
|
||||
FnPQFvbvhFFFbvBwScjhzcqSLLSzSN
|
||||
bWdgrWwwFWbgzFWzrmNbdPqttChMSRnmqSPSnqtMRM
|
||||
lcPJLDDPPfpMBCRJBtQtMh
|
||||
lGDGjTGLLDHPPGjlPTsswsbHNFsNrFNFsrzr
|
||||
VmtHfVhBLHVtlhphjZMdnQQZZqZmQDdzQQ
|
||||
CPFwPWrvWgrfNgFPCMqZzMDDbznFTqqzDQ
|
||||
NNPsfffPCsBLjpVltV
|
||||
ssdBBJqJhlTJLsjTJqFFmnmmnnrcmpprmmmPcRlf
|
||||
gqtqzSgWQWqmnRPPcNmmQM
|
||||
GqbSVtGzvgvgWbZjjBhTdhBsTZBJBZ
|
||||
jhNBsPDzLjsVhLSNzgvcvbcwbBWFcgtWCc
|
||||
ZQQTTHHnGpMtnpdHpQJfMgrvWWFqbcWWGgrgwCCwwF
|
||||
nHpmMnQQMmHpRnHRmMJnnTShPzljzjSNmSDhLsNSPtSh
|
||||
GdqnBGFdlqzFnwdSCQZjZLLDZjZRvZLDVvgQ
|
||||
PsptsTcftMfcTfhTghVDvvjnRNjVZnvV
|
||||
WtPfJTfftJcMTrMnpccFwlCSCGFGCbCwJSbqBl
|
||||
GjFLGhjRwFjNSjSdJCBBdQJddbBc
|
||||
MVvMMHRzVtHlvlcQBQJHqdpQqCBC
|
||||
vDgVztvvmrgrVRrMmsrsmZzZnWhGnNhGWTLfnLwTLhLTjngL
|
||||
VljjQJSsrjjrCglsCjsgjVVfDLdZGMdvvGdQMzmvzcDQMc
|
||||
HqPBtcpRWwtHbbFwBHZfmfpDfvffDfMfmGvM
|
||||
PwHNbcwtqFqnwtNNqPNPPWBTThjhhVTCSJTThssVnSlJJV
|
||||
GCccNCrrnCrpnzrnCDPcDDrvHHTBqTPhswqhPTBTTwBhTj
|
||||
VfNmRtZgWWHdBdswdjZv
|
||||
SmtQfgNmVFgVLVLVmrnMpcDLGCGLGDMpCp
|
||||
CrdZdZmPPjrQdRPRDqDLBqBLBSWgWgLDzF
|
||||
sQhTNphsVbhhhMJfhNVGqltVSzSllBzStlzFFFWB
|
||||
hsMpwQhNMZmPmrwHRj
|
||||
cNVpSVRpLHRLsVWWfnfsCshW
|
||||
jvqjTgqZPlJZmbPPfbpswsPb
|
||||
vlqdTZdtJvqdZjgqZrtRpQFtLFRQczHGzt
|
||||
JJQndVQnQgTfNvGf
|
||||
ljpbWbmNbDlGTvggGvZf
|
||||
mpmRbMmmNDFDmScpzCsdzrnJrsCzrrnM
|
||||
tNFtNFFzzjjzjBtVNZVbjZGlpSvTllpWwvnBlWGGBGCC
|
||||
fPdcrrgPHrHMMMWlppGJSPwGSnGv
|
||||
fmrqrhhfhdRddHrhQqQrfnLZjLtNttZjjRtzjFtRNj
|
||||
sphRcpQRhfmnmfpptg
|
||||
WVPlGLlSjCjSlGSHJJWZdmbmfvPmmnftbbgDdt
|
||||
LJjjqVNjlnCTRcRhhsNcFF
|
||||
vwwqttFjwgClRNCCvGNmZZMmJsPJjJpTdMpsZd
|
||||
fBLVHHHrFnhHhnrVSTmfdPdPccTTPsMfsJ
|
||||
QzVWzznzFbWNGNlt
|
||||
vjMddVVmnWpdMndjvhhWfNLpfBsfLLZLBBSqqTZq
|
||||
RFlrzQJPSRGzzzzgBZNsgBZTBflfgf
|
||||
cQFDRHFDDGCJShCnvwVnnhCn
|
||||
hgjlpRRLlPJJhTLJMDnwBndSPBNvMqnN
|
||||
FGWVfZsmCbmVzrvtwCSMtMdnDMCw
|
||||
VsVmVZfVQDmVFrrmzmGrHHTJgJjhHJcllglLQJRL
|
||||
rrTVcTBgsjTffmfWHZTv
|
||||
JLdnDlpGlGSLlpwJpHZfFvRZnWzWrHWqFH
|
||||
wQDpDrdSlSCblCdwdSLlwQGBthPMsghNsVNVtCNNhNPjhs
|
||||
CtCMvNhDMHfDDdffqtDtCflpJlBpvmWWJWwlpwFFvjwB
|
||||
rGSbVGZrSsFJjlmBFZWp
|
||||
rbbQgzVGrFVSPPGqfhftfqztNtqHtt
|
||||
lMGZCGphllZDNshNNmHHND
|
||||
PLwjVwJVsHmRrZZw
|
||||
ffSdzjfZSjtjSjLtLLFFFGqFzznCpCnCBblQ
|
||||
CqRnlzHCRWTlHPTZVQrcQtFsQFTcrQ
|
||||
DfJcdBDBcftQjsrsBtjZ
|
||||
JDfdGhSvNGhNfffGSfRznPvcRWcqCqmlvlcn
|
||||
JPhBBBQCnCJCMhnhMZRrRZgbDgrWrNbglDgR
|
||||
jLtSTwtsShwRNpRWrh
|
||||
FLLSHsjGLGczvfPfJdfhddnHPC
|
||||
BjHBNrWmTjFgJngbJhWd
|
||||
vsGttMDtwCMQCJnqqqFJsggqdg
|
||||
GFtDSwwMpTrzSSfcfm
|
||||
rnWDQvpwWpDDcPjFPPHZjVDZ
|
||||
CTJCRmCJcZZZHCCQ
|
||||
LdlmdQJNpnLWbrfL
|
||||
VdTdcVTZwCRGVGGMVmttlF
|
||||
gnrsbngfgQSpBfpMBBBpSgMNNJbmGmlqGDqDNlFFJlGNFz
|
||||
gprgQhgpMMMPsrRTCdPZwCwZZCRH
|
||||
cHlCVGbbWHWqRNThhcNcmh
|
||||
MwQDzpwdJwpBpPDQvrhShfLTTRLfLdjfNRqS
|
||||
JwMBBrPsPDwQMDPPBPQJwMrvWHFbHHlgbsGnnWHnFnRGlblF
|
||||
PQPjPDjRRQSFLSlgSmLlfh
|
||||
zpLdBddbNCdqGbWJGWpJWWlsFsmmFpwfflFgfHwFhgmh
|
||||
nJLdLVnzqqbjRctcPDQVTP
|
||||
JdztScztPdSWLJLtgMbCjhvlbPRbjbMvCh
|
||||
VZrqfQcFQwGVVFqfrTFTNqhljRHDMvMMGhRDRRHGbDhG
|
||||
NZQNVQQpQmrZFQQFwQQVVZgBszJJgznstnmtcztdBSgs
|
||||
nFHLNJzFbLJGGLMlTTRZbZRhWRTr
|
||||
wVmgBBmtmwlqlWTwTM
|
||||
sdvmgcPsCPPQQSMz
|
||||
SccCqmQmgBmppLQmpSMjjlJzzsNPMDRbPNPlJM
|
||||
VHZvwtZwhZHtdTwrVbNsljlRDlJPDhzsbN
|
||||
dZwftVRftmcgpBCmBf
|
||||
NTTlVlgNSflqbphFFhNbFp
|
||||
wmmLmjwzwbWGLjRmtZZdhZLFtQQLQBFh
|
||||
RvjbMjjvMzMWbDWwvzPjvmWSfVfsTlVVPVgTgPfVsnnnsJ
|
||||
BsBsZHZNdWwsNdrzgCrMMqsjzzMC
|
||||
flfhVWFmLrhQzCCh
|
||||
fVbmFSpnSSmtnPZvdWbwvdvdHZ
|
||||
NsZWWWWLsBZPhfsLmPhcFCCHCMMrqfqcvHMfHH
|
||||
nThSllnplGlMpvFRcCqrrr
|
||||
DnTwSztgzlDnVGTwztmdZhmLdJdNDshBdsWs
|
||||
RBBGTFZGglMHvrtcgSdnNgjg
|
||||
DmVcbmbJmwJDJzVVwzJfmfstnztvjnNjvNSpdptvzCnpjj
|
||||
DsLcfLmbhVQssQJQscWRPBZZMMRLHFHZBGMG
|
||||
FVvhVnhFnFhmvFhVcMBHLgcPClrqqrtqCppldrRRTppldg
|
||||
QLWfDNwsQLtlrrCtDdpq
|
||||
sJwZwLsGJWGGwzzWZNbWNLjQHSVhvHSnhcMFcbVmnvcchSBS
|
||||
jTMNMrHBJWWDffRqfDBqfD
|
||||
QmSFphtQqQmVmqVnPnPlpwgfnRnDPl
|
||||
VqFmLFbLhmZhGFGmCmGtZLtJWzWHcJrNrHMccjMscMHzMZ
|
||||
hGPGmbfPzbPfgdMdWGqBGQcqpp
|
||||
nvFTvDrTdNZZlrjnMHHHpBBcppqq
|
||||
rNlZZNLvRdRCRFFwZwhgbmSJPSmPfhfwhS
|
||||
vjdbFWTtFRRvtvZZvdWJWbGjLhCcnrrrNqLNCPqchShNqc
|
||||
QHQVlDsMfmmDMHDBdLdCSLnhNLNNfqCd
|
||||
VQHsMDpHlzMBBwlsmMzmmlVwptvTWdvJdbvJtRTWgGFJJGtR
|
||||
nSScBcnbbFSQVdBFBtWpwtvtPbTZthtTvT
|
||||
pRzHpGjCDGzHGCGsThqqwZwPhCtvhTqZ
|
||||
NzlzjDDpNldBFrlfFQ
|
||||
qJlDlPPWppgppqPlplpfdvgnbMfGbdgCghMdCM
|
||||
QWTWZcSsWbvVvTnhfC
|
||||
tRFLwZrcrWzzlJmtBqlm
|
||||
HMNMvvzzNcmfNmfbhs
|
||||
qVcwCgjCLtWRSLsTPbmPfmTh
|
||||
RtWCJgddWRtCJdWWgdBjwWWwpzMFpHGprcBGFFnGHQZHQGpF
|
||||
gZgBDgDVGDGjmDZRtgjvVvtQdnLrcRcrdfdfCcnlscsJsn
|
||||
WTqzqHqNzpHpwzNhMHNwWPbQCQcCLsnCrLLfcrffNflcNn
|
||||
zHTwwpTPzTTwlFTFzwqzPbwZGgGZZBtmGGvGmBGZVFStFZ
|
||||
znlSSzfzTcmmfcCt
|
||||
PHWWGpqgPShPMwGwqJFTVtwtCVTCmTJcFc
|
||||
qHqqSggLrRLBbvDDdndzRQ
|
||||
WBddBQWZWWQqqQFMWfmrWsJnmVJJNDDVJGsLmHmLDN
|
||||
PTgCjvCCPPPzSZGJVLsVZCHHnH
|
||||
pzwtPTvzTjRTPtwSjPSzRgBbWMBfMwwZfbWrMrZFqFFM
|
||||
BqDwVqdqlDlblQMf
|
||||
ZcCWWcWzvJZjcPjZZZfTHfQJQHThqpMbQQJf
|
||||
LPCcZcczZLgCjvPWgvstjsjmRRBdmGrdGdmSFGnFrtGmqr
|
||||
CBvgQssVzfCBQSgvvvfmrlGrCtMGwthJlJtbrh
|
||||
TpLqLRFpqdRpRTfNPtRmrMMtMlMMmlMJlt
|
||||
PZTjqFFTHZZNZpqcVWzVvgzcWnSWfBDD
|
||||
SVSTpgpVpdNbpcVdfjcNfbcJnqsltcJPvRJqRwQqlQsJls
|
||||
zhWzDLmFHhmrWZmmzHJJQlnswqsvttrstQqs
|
||||
zGtZFGGCmZmGGFhLBWBGGFdgVjgppMTSTgMfCNfVVSdj
|
||||
CzjNJGcnzQJltPHttcPHTP
|
||||
bLVsqLbLmSSVrqmdhVSmsVFFprfrFWrwTTWWWZpFPtlP
|
||||
ssDsMqLqhvmvhdmdvzRCnQgRzzBjgnlNCM
|
||||
TzTLzzSGRlRSjWzlWRzHGTpNhPhJPmdnNPPbhlbPbdhfPh
|
||||
mBCDBVrCqVQvQMBcVcqBrBDsbtJfnZNbJndNNhthZNJfPZPs
|
||||
wMCrqVvBzmzHTGLw
|
||||
NbfwfZPPdVNPdBdQBcmQzrQz
|
||||
nnWqHLWGFMDFDLDjsqnHLsrQGzmJczmQrgJmJGZmQrgJ
|
||||
FFWRsHMHCZCWFwRwphpvlfTTpp
|
||||
PclPlVZvLDNvVZSLSMvvDttmtfzFtzHqtqtzzccCFc
|
||||
jrggQGhjQsTDbrbJjJQqzzCsdtzzFCdHqmBBHz
|
||||
WGDgngwrQggZMNvMWPMRRV
|
||||
wNgpMdMMcdSscccNcLLTbtQJtQJQltJwFtlBlzBt
|
||||
HHGhrLrCvHWHCPhrWDtnBllnQbfQftGnfnBF
|
||||
HvLjWCLHPZvHHHZjjrqVTTZVcppMgNNNNSpS
|
||||
QQrwQmvWQjgTfvBjfffrSDcrqSqDDVLctqqcVd
|
||||
GnHFnGhGplGMlHMNhzBzlLPLVcVNCPDqVNdcqLdqtV
|
||||
GnMGpslMhGsRzzHzGsZFZQJTTmWfBbvfgfgJRfbwbW
|
||||
MRCtSwMhvjCGtvMZDVWpVZJlVccNDlpb
|
||||
gdLQFFwwLfHJWnQlcJJbWc
|
||||
rdqdmqHLTLmsswsFHLFtMPRMCSSRtSjTPMPSCR
|
||||
jmCCnLCLZjZjRjQTLZQhGPGhhzHhDRGRDzwzwh
|
||||
stlJlrlJJcSSfSMMzPfhhGhzpwhpNwhD
|
||||
rbrbBcSlWmdZWjDnTm
|
||||
PNBRNnnqQRNfVfRtVVzgFLLttpSwgzzzmFFF
|
||||
fcWlcbvvCFzLbwLw
|
||||
rlrMrhTJhDcTTfhRNqHRQPQRQNQB
|
||||
TrprpprRVVfpRpVqTVpzDdvmvbbCchhcttqcthSMdd
|
||||
JlnZnFlsMBZnJHlsLsCLbSNtbNhdbbShCScm
|
||||
FlZjjsHHsnQFQwTDzMRRpGRR
|
||||
wHWzwCTTqJhzzvJhWHWhqJWrFsFQrrrFCfFfgjjgjprfsp
|
||||
DBRmZRtZLbnRBGSBmtGSLpjBrrsfrgsTQVrVrrPrgr
|
||||
DLnbcbtLtmNNmbRcGbcGmHzlThNNhqJTHdvqvWlHJh
|
||||
GSNqjRcqflNLnCTTWrWn
|
||||
BmwQtmtJwPwmzMwQtHtVssvrnpWTTnsTTgpVCLCs
|
||||
DBBQHJJrzhzQDDfSljRfhccfcdZf
|
||||
wtgtChCwzqgLzjggqtHtjFHHFcnPfdRDfZZVcPfVZZfGnfdm
|
||||
vBTrRTTWGGmcTDVD
|
||||
SJMbbpWslJblSSNzNsztRChzqRCj
|
||||
gBHHCtVCSHMQlfFTQqCfmq
|
||||
WrpdwjbwbwQGlPqSqblP
|
||||
wWDncWrDDNdWNRjScScjpzvHZtBMZtJsvLVgvzssBsvs
|
||||
VppWpVfmZPBlnmrGBzhttMzMpctLLcChSh
|
||||
FwgLJvRdHcwMzSzjzc
|
||||
QvbgdQLQgDvsqvqRHRDdDQDBWmBGBflnVbZmZmmnBBWrmW
|
||||
SqShwLFCQGpDHCtZCWpW
|
||||
bdHPHjTbJdsMnPHPbdjgtnBlVlBnVgtZpDBpWV
|
||||
bdmPcjbjMNMvvHbTcQRNfRwRwLffwwqwNF
|
||||
zdRHTpQTQHQnpnnQRHTsNNlJSJWmzJmJllNmSG
|
||||
FBbRvLbFRwLqbbVgBVqqLFqJtJNcltsSGmgmGtNtgWmstm
|
||||
FLhhfvvVwvjqfLRBqLVqbwqZQrTTpHMHjdrpnnDPDQCdCrpC
|
||||
JgjzvbJCWgbjgGbJWjRhgNPGHHBMtqBStZZsHMSsBqtD
|
||||
cfQdwQFdQQppnVVnlFLLBsBZMhqPlPMMqBSHDtHM
|
||||
wnQhcnVddmdWgjvjmvRjjJ
|
||||
QpcRtndvsLcVJtRSzWSlWjzSbjjWBv
|
||||
qGZPqCTmGPqgGTCqHgCqZCPFWbbBNBMNBbdBMlWWrbjlMbFl
|
||||
qhHDGhCmPhZHgDmDVQthttRchLwLdwcc
|
||||
srpPMwlMmsrGFGswvDRhRWRDJJJchJ
|
||||
fSgBbCBNnBTTgCNLTCRJhRJVWhTcVVVFFJdR
|
||||
SbBnnLNZCLFQCZjnCnZFjPrzqmlMmmsrpzrlsmtt
|
||||
BBsfDfsBDSWRwlLqmWCpWcllrl
|
||||
nQMgMnnnhdntgMBrCdpNNLNlNqLqLl
|
||||
FnQFHzPQJjJGRBGvfR
|
||||
lRnVRFFlgMCRVwLgFZRnZQHWdcftHdmcJHmmMdzzfz
|
||||
DGBqGQbhhBDbSBpGDBzqdNHJdtmcWdqdmtcm
|
||||
bjbsBvjhSlVsPRgLQl
|
||||
dDLbRdTMRJMbFRzZBfzNSjtNBzBD
|
||||
PmgspqqVrppTVrvrsPhhfQwZBwNjNtNffzqqfwwN
|
||||
mCcmsngrPvpVTssCVsvsPLRRJllGFlnRGbMJMWWlJJ
|
||||
fGlGZHRRbwgPbZRRNCdcSWpncnQtQWlWcWpW
|
||||
JrTLJgVvVLQQvtSvQncQ
|
||||
JrrrmMTBVTmjBMrVjrshmJzgCfzRPCRZPGHfbwNPzbZHNH
|
||||
qqqlDDZzVVnNqHDDFFFNlQpzjrTvsvzTbgJQQggjJp
|
||||
cWPWcCmMfCMWdtPMhMbQQQjGGjpdvjTbjgjr
|
||||
WtMSBCtCwchChMfBWtcPnNVNqZZLDRNqTRnnlwHn
|
||||
mvQQnhBvhmvBmncmZBclTZTQccRFNFFdqFFgVqSRrgFrppNR
|
||||
MjzJPzGPfffMCjVVjfPHLCFRNFStqrdRSdqdNGRqNptq
|
||||
HDJHPjDJLfjbzfwPjCzCWWTwlmQhBnsWBvVsvBvZ
|
||||
RVjcshhscQhrVjhvzjVfDNnzGtftmDHFttFGGf
|
||||
qLcBCCMBJJbTdBDnNtdfnmDG
|
||||
WpZgLLclTclRwgjgsrwsvj
|
||||
shhhltNPcDtlNcNMcsctNtppLZvWWFLTFFZpTZDQgFLT
|
||||
dRgJVzRHbqnLpTWQvLLJfp
|
||||
mCVCdzqHndbqHCrVqRrmbwtNBsmPwNmScPgtPhBclw
|
||||
bDDZMDrFPsrsMcsrbJZJdMMGpSzpSbwRSSRGpCHCGzlhCC
|
||||
BWWNQjBLQVHhlGpSCmwj
|
||||
ffwnNwfgtnNgVVwfNWBWnFsMJTJTcPFJcTFDsrJstJ
|
||||
vQbQLQBpBvbvpHplHNTHWGZDngntZCQGgZhGhtjG
|
||||
rqccPPmcrffRmsmCjVgnrGChChDjgW
|
||||
fqRJsJMSlSzSWTbT
|
||||
brsjjJPJwrJJsrRRlllNQGWQpwppCtfGGtWzGGMQ
|
||||
ncBqqLTDnmLgVDZVnBDmdtVVtMzWWdMCQdpQWdVz
|
||||
hDZgTSSnTzNPNFSFPF
|
||||
VZVJJtWTsfTVVWsJhPWrCjzSBJlHSmjJCRlNSSlz
|
||||
CqMpwccgvvgLnvLbMMRRjBNHzjmGmwNHlmlN
|
||||
gLqqvpCDfVDrTfVW
|
||||
CNMDGNPPNJCGbLnTffsTLT
|
||||
tcBBRlrBdQrtmtWFjjbnrTjjFbjr
|
||||
cTQQhcmvcBRcwDMVDZZPPCJh
|
||||
mBCdgPLgZmLfGmfvGhtRQJWjtjQGQhtN
|
||||
pMwrVwbwHMsqcTWQhQWzggTTWp
|
||||
nnSMwrlrsmSZgvvmDd
|
||||
WNSzpCzNzqzNdmqrRHrrLHFrJH
|
||||
MtPfvnGMPnMcbnRtDHTRFFDrmJRQ
|
||||
PcBsfPPHPGGfcSzZjNjpNZZdCs
|
||||
mDCZVLDhWVSDCRvGtsGgGRHl
|
||||
JjPwPNdcPnjPdcwNltHzzGmgGJzQJJRQ
|
||||
dqfjnNmwmbmWrZMbMrThhB
|
||||
qtBpNZFpBGFNfZNPmZPmQmHrmPPPTz
|
||||
LLwJLvDvlWWLHdwDrVcCRcDVzzVVcV
|
||||
sMMwvgjnMvjvnlsvNFBqfGHFqHGjtSpS
|
||||
MmZZsFgwJTdTMdgmZdZRgFhDHhPQPPnRPhCrHhnnrPDD
|
||||
fBcLlNNpQCDLDJJC
|
||||
jSbWWlWpBpclWlWpNWlVBbWVdgwswFJmFJsGtdMggZFGbZwd
|
||||
CMVQVMLLMFGRCMWQttnqqwQwhqsm
|
||||
pJzlczSpPpPgmsqNhmPGDstq
|
||||
gZgTccZGGpzdpjclGRVMVRFRMFvHRLRdLf
|
||||
FMWMSBtStZqZWQtFtScWWSZmHPVJJVHwwlTgmgbzQwbwTJ
|
||||
jhGLhdjNjsLvLsshzHJPVdVmmbzHzdHJ
|
||||
jvDRNjnDNGRCzjLzZZpqnrFBSccWrMcB
|
||||
zggmthDDghHvtrdgrVWfSBRwTHLWHwsBWw
|
||||
PGGjpCjQnJQGJcJnnQpjFWVSsZWVLRZLBcsWSZBRWS
|
||||
FGQlpnJCbqqGGRCjjnlCqGMtdNmmmvdNmmmzvhbrmgMz
|
||||
TstvBTdgBhqTsdTcPlfCSrNMrNnrCNNSNNgp
|
||||
HwLQwQDZzDjnDbmMhNSnmm
|
||||
FZLVzLLQHRRzwWHjdPlJctlJtlsllhRs
|
||||
fBtPsMDDswHvBmmVdBlSBRcGGnhVhg
|
||||
LWJbrpFqpTLTTjqqNWlhnRGGSnhrcSdlRlsh
|
||||
JWNbbpjJzTbNNNJNJMvmvfZHvzDsHDCsZw
|
||||
LPGnPNLtwGhFFnJPfsqpVVszzpsP
|
||||
TcWdvlrcWddggrDBDDdDMmWzRJqfVQZqmsfZsRQzZfZzQJ
|
||||
TldWrMrDdlDCDdMTcwSLVCSShLNSwHjhGF
|
||||
JGsWWWQsJmPwQWbBPmccbcbqFfMMpFDVCDFVFVCDqqfFwD
|
||||
ZtLnlvLnNtvLndnCmfMVSmVCClfpVp
|
||||
zTzZtjnZNLNmZvdtznntHHZJbBRGBRQWcJGbGsbsJRPQWT
|
||||
MLmlMTPtQtMNlhbqbbqhflBB
|
||||
rcrvjpSvScbRbBvbDBPG
|
||||
ZZJzSHpzPrJzHFmMVMFmHCLNtV
|
||||
14
2022/days/03/src/main.rs
Normal file
14
2022/days/03/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
let _structured_input = utilities::parse(_input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&_structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&_structured_input));
|
||||
}
|
||||
54
2022/days/03/src/part1.rs
Normal file
54
2022/days/03/src/part1.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part1(input: &[Rucksack]) -> usize {
|
||||
input
|
||||
.iter()
|
||||
.map(|rucksack| rucksack.0.intersection(&rucksack.1).next().unwrap())
|
||||
.map(find_char_score)
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
Rucksack(
|
||||
HashSet::from(['v', 'J', 'r', 'w', 'p', 'W', 't', 'w', 'J', 'g', 'W', 'r']),
|
||||
HashSet::from(['h', 'c', 's', 'F', 'M', 'M', 'f', 'F', 'F', 'h', 'F', 'p']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'j', 'q', 'H', 'R', 'N', 'q', 'R', 'j', 'q', 'z', 'j', 'G', 'D', 'L', 'G', 'L',
|
||||
]),
|
||||
HashSet::from([
|
||||
'r', 's', 'F', 'M', 'f', 'F', 'Z', 'S', 'r', 'L', 'r', 'F', 'Z', 's', 'S', 'L',
|
||||
]),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['P', 'm', 'm', 'd', 'z', 'q', 'P', 'r', 'V']),
|
||||
HashSet::from(['v', 'P', 'w', 'w', 'T', 'W', 'B', 'w', 'g']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'w', 'M', 'q', 'v', 'L', 'M', 'Z', 'H', 'h', 'H', 'M', 'v', 'w', 'L', 'H',
|
||||
]),
|
||||
HashSet::from([
|
||||
'j', 'b', 'v', 'c', 'j', 'n', 'n', 'S', 'B', 'n', 'v', 'T', 'Q', 'F', 'n',
|
||||
]),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['t', 't', 'g', 'J', 't', 'R', 'G', 'J']),
|
||||
HashSet::from(['Q', 'c', 't', 'T', 'Z', 't', 'Z', 'T']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['C', 'r', 'Z', 's', 'J', 's', 'P', 'P', 'Z', 's', 'G', 'z']),
|
||||
HashSet::from(['w', 'w', 's', 'L', 'w', 'L', 'm', 'p', 'w', 'M', 'D', 'w']),
|
||||
),
|
||||
];
|
||||
assert_eq!(part1(&input), 157);
|
||||
}
|
||||
}
|
||||
78
2022/days/03/src/part2.rs
Normal file
78
2022/days/03/src/part2.rs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
use crate::utilities::*;
|
||||
use std::collections::HashSet;
|
||||
|
||||
struct Group(HashSet<char>, HashSet<char>, HashSet<char>);
|
||||
|
||||
pub fn part2(input: &[Rucksack]) -> usize {
|
||||
seperate_groups(input)
|
||||
.iter()
|
||||
.map(|group| {
|
||||
//manual implementation of intersection because doing chained intersections is annoying...
|
||||
group
|
||||
.0
|
||||
.iter()
|
||||
.filter(|c| group.1.contains(c))
|
||||
.filter(|c| group.2.contains(c))
|
||||
.next()
|
||||
.unwrap()
|
||||
})
|
||||
.map(find_char_score)
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn seperate_groups(input: &[Rucksack]) -> Vec<Group> {
|
||||
let mut output: Vec<Group> = Vec::new();
|
||||
for group in input.chunks_exact(3) {
|
||||
output.push(Group(
|
||||
group[0].0.union(&group[0].1).copied().collect(),
|
||||
group[1].0.union(&group[1].1).copied().collect(),
|
||||
group[2].0.union(&group[2].1).copied().collect(),
|
||||
));
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = vec![
|
||||
Rucksack(
|
||||
HashSet::from(['v', 'J', 'r', 'w', 'p', 'W', 't', 'w', 'J', 'g', 'W', 'r']),
|
||||
HashSet::from(['h', 'c', 's', 'F', 'M', 'M', 'f', 'F', 'F', 'h', 'F', 'p']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'j', 'q', 'H', 'R', 'N', 'q', 'R', 'j', 'q', 'z', 'j', 'G', 'D', 'L', 'G', 'L',
|
||||
]),
|
||||
HashSet::from([
|
||||
'r', 's', 'F', 'M', 'f', 'F', 'Z', 'S', 'r', 'L', 'r', 'F', 'Z', 's', 'S', 'L',
|
||||
]),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['P', 'm', 'm', 'd', 'z', 'q', 'P', 'r', 'V']),
|
||||
HashSet::from(['v', 'P', 'w', 'w', 'T', 'W', 'B', 'w', 'g']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'w', 'M', 'q', 'v', 'L', 'M', 'Z', 'H', 'h', 'H', 'M', 'v', 'w', 'L', 'H',
|
||||
]),
|
||||
HashSet::from([
|
||||
'j', 'b', 'v', 'c', 'j', 'n', 'n', 'S', 'B', 'n', 'v', 'T', 'Q', 'F', 'n',
|
||||
]),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['t', 't', 'g', 'J', 't', 'R', 'G', 'J']),
|
||||
HashSet::from(['Q', 'c', 't', 'T', 'Z', 't', 'Z', 'T']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['C', 'r', 'Z', 's', 'J', 's', 'P', 'P', 'Z', 's', 'G', 'z']),
|
||||
HashSet::from(['w', 'w', 's', 'L', 'w', 'L', 'm', 'p', 'w', 'M', 'D', 'w']),
|
||||
),
|
||||
];
|
||||
assert_eq!(part2(&input), 70);
|
||||
}
|
||||
}
|
||||
93
2022/days/03/src/utilities.rs
Normal file
93
2022/days/03/src/utilities.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
use std::collections::HashSet;
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Rucksack(pub HashSet<char>, pub HashSet<char>);
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Rucksack> {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let (first, second) = line.split_at(line.len() / 2);
|
||||
Rucksack(first.chars().collect(), second.chars().collect())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn find_char_score(input: &char) -> usize {
|
||||
if input.is_uppercase() {
|
||||
*input as usize - 38
|
||||
} else {
|
||||
*input as usize - 96
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_find_char_score() {
|
||||
static CHARS: [char; 52] = [
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
|
||||
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
|
||||
'Z',
|
||||
];
|
||||
|
||||
for character in CHARS {
|
||||
println!("{}", character);
|
||||
assert_eq!(
|
||||
find_char_score(&character),
|
||||
CHARS.iter().position(|c| *c == character).unwrap() + 1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = "vJrwpWtwJgWrhcsFMMfFFhFp
|
||||
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
||||
PmmdzqPrVvPwwTWBwg
|
||||
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
||||
ttgJtRGJQctTZtZT
|
||||
CrZsJsPPZsGzwwsLwLmpwMDw";
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Rucksack(
|
||||
HashSet::from(['v', 'J', 'r', 'w', 'p', 'W', 't', 'w', 'J', 'g', 'W', 'r']),
|
||||
HashSet::from(['h', 'c', 's', 'F', 'M', 'M', 'f', 'F', 'F', 'h', 'F', 'p'])
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'j', 'q', 'H', 'R', 'N', 'q', 'R', 'j', 'q', 'z', 'j', 'G', 'D', 'L', 'G',
|
||||
'L'
|
||||
]),
|
||||
HashSet::from([
|
||||
'r', 's', 'F', 'M', 'f', 'F', 'Z', 'S', 'r', 'L', 'r', 'F', 'Z', 's', 'S',
|
||||
'L'
|
||||
])
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['P', 'm', 'm', 'd', 'z', 'q', 'P', 'r', 'V']),
|
||||
HashSet::from(['v', 'P', 'w', 'w', 'T', 'W', 'B', 'w', 'g'])
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'w', 'M', 'q', 'v', 'L', 'M', 'Z', 'H', 'h', 'H', 'M', 'v', 'w', 'L', 'H',
|
||||
]),
|
||||
HashSet::from([
|
||||
'j', 'b', 'v', 'c', 'j', 'n', 'n', 'S', 'B', 'n', 'v', 'T', 'Q', 'F', 'n',
|
||||
])
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['t', 't', 'g', 'J', 't', 'R', 'G', 'J',]),
|
||||
HashSet::from(['Q', 'c', 't', 'T', 'Z', 't', 'Z', 'T',])
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['C', 'r', 'Z', 's', 'J', 's', 'P', 'P', 'Z', 's', 'G', 'z',]),
|
||||
HashSet::from(['w', 'w', 's', 'L', 'w', 'L', 'm', 'p', 'w', 'M', 'D', 'w',])
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
10
2022/days/04/Cargo.toml
Normal file
10
2022/days/04/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day04"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
once_cell.workspace = true
|
||||
regex.workspace = true
|
||||
1000
2022/days/04/src/input.txt
Normal file
1000
2022/days/04/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
14
2022/days/04/src/main.rs
Normal file
14
2022/days/04/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
let _structured_input = utilities::parse(_input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&_structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&_structured_input));
|
||||
}
|
||||
27
2022/days/04/src/part1.rs
Normal file
27
2022/days/04/src/part1.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part1(input: &[(Range, Range)]) -> usize {
|
||||
input
|
||||
.iter()
|
||||
.filter(|tuple| tuple.0.complete_overlap(&tuple.1))
|
||||
.count()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
(Range::new(2, 4), Range::new(6, 8)),
|
||||
(Range::new(2, 3), Range::new(4, 5)),
|
||||
(Range::new(5, 7), Range::new(7, 9)),
|
||||
(Range::new(2, 8), Range::new(3, 7)),
|
||||
(Range::new(6, 6), Range::new(4, 6)),
|
||||
(Range::new(2, 6), Range::new(4, 8)),
|
||||
(Range::new(19, 30), Range::new(5, 18)),
|
||||
];
|
||||
assert_eq!(part1(&input), 2);
|
||||
}
|
||||
}
|
||||
27
2022/days/04/src/part2.rs
Normal file
27
2022/days/04/src/part2.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part2(input: &[(Range, Range)]) -> usize {
|
||||
input
|
||||
.iter()
|
||||
.filter(|tuple| tuple.0.any_overlap(&tuple.1))
|
||||
.count()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = vec![
|
||||
(Range::new(2, 4), Range::new(6, 8)),
|
||||
(Range::new(2, 3), Range::new(4, 5)),
|
||||
(Range::new(5, 7), Range::new(7, 9)),
|
||||
(Range::new(2, 8), Range::new(3, 7)),
|
||||
(Range::new(6, 6), Range::new(4, 6)),
|
||||
(Range::new(2, 6), Range::new(4, 8)),
|
||||
(Range::new(19, 30), Range::new(5, 18)),
|
||||
];
|
||||
assert_eq!(part2(&input), 4);
|
||||
}
|
||||
}
|
||||
79
2022/days/04/src/utilities.rs
Normal file
79
2022/days/04/src/utilities.rs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Range {
|
||||
start: u16,
|
||||
end: u16,
|
||||
}
|
||||
|
||||
impl Range {
|
||||
pub fn new(start: u16, end: u16) -> Self {
|
||||
Self {
|
||||
start: start.min(end),
|
||||
end: end.max(start),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn any_overlap(&self, other: &Self) -> bool {
|
||||
self.start <= other.end && self.end >= other.start
|
||||
}
|
||||
|
||||
pub fn calc_overlap(&self, other: &Self) -> Range {
|
||||
let overlap_start = self.start.min(other.start);
|
||||
let overlap_end = self.end.max(other.end);
|
||||
Range::new(overlap_start, overlap_end)
|
||||
}
|
||||
|
||||
pub fn complete_overlap(&self, other: &Self) -> bool {
|
||||
self.calc_overlap(other) == *self || self.calc_overlap(other) == *other
|
||||
}
|
||||
}
|
||||
|
||||
static PARSE_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^(\d+)-(\d+),(\d+)-(\d+)").unwrap());
|
||||
|
||||
pub fn parse(input: &str) -> Vec<(Range, Range)> {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let cap = PARSE_REGEX.captures(line).unwrap();
|
||||
(
|
||||
Range::new(
|
||||
cap.get(1).unwrap().as_str().parse().unwrap(),
|
||||
cap.get(2).unwrap().as_str().parse().unwrap(),
|
||||
),
|
||||
Range::new(
|
||||
cap.get(3).unwrap().as_str().parse().unwrap(),
|
||||
cap.get(4).unwrap().as_str().parse().unwrap(),
|
||||
),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = "2-4,6-8
|
||||
2-3,4-5
|
||||
5-7,7-9
|
||||
2-8,3-7
|
||||
6-6,4-6
|
||||
2-6,4-8
|
||||
19-30,5-18";
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
(Range::new(2, 4), Range::new(6, 8)),
|
||||
(Range::new(2, 3), Range::new(4, 5)),
|
||||
(Range::new(5, 7), Range::new(7, 9)),
|
||||
(Range::new(2, 8), Range::new(3, 7)),
|
||||
(Range::new(6, 6), Range::new(4, 6)),
|
||||
(Range::new(2, 6), Range::new(4, 8)),
|
||||
(Range::new(19, 30), Range::new(5, 18)),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
10
2022/days/05/Cargo.toml
Normal file
10
2022/days/05/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day05"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
once_cell.workspace = true
|
||||
regex.workspace = true
|
||||
514
2022/days/05/src/input.txt
Normal file
514
2022/days/05/src/input.txt
Normal file
|
|
@ -0,0 +1,514 @@
|
|||
[S] [C] [Z]
|
||||
[F] [J] [P] [T] [N]
|
||||
[G] [H] [G] [Q] [G] [D]
|
||||
[V] [V] [D] [G] [F] [D] [V]
|
||||
[R] [B] [F] [N] [N] [Q] [L] [S]
|
||||
[J] [M] [M] [P] [H] [V] [B] [B] [D]
|
||||
[L] [P] [H] [D] [L] [F] [D] [J] [L]
|
||||
[D] [T] [V] [M] [J] [N] [F] [M] [G]
|
||||
1 2 3 4 5 6 7 8 9
|
||||
|
||||
move 3 from 4 to 6
|
||||
move 1 from 5 to 8
|
||||
move 3 from 7 to 3
|
||||
move 4 from 5 to 7
|
||||
move 1 from 7 to 8
|
||||
move 3 from 9 to 4
|
||||
move 2 from 8 to 2
|
||||
move 4 from 4 to 5
|
||||
move 2 from 5 to 1
|
||||
move 2 from 5 to 6
|
||||
move 7 from 8 to 1
|
||||
move 9 from 3 to 9
|
||||
move 11 from 6 to 5
|
||||
move 2 from 6 to 7
|
||||
move 12 from 1 to 4
|
||||
move 10 from 2 to 9
|
||||
move 2 from 3 to 9
|
||||
move 1 from 7 to 5
|
||||
move 4 from 7 to 6
|
||||
move 2 from 6 to 1
|
||||
move 5 from 1 to 6
|
||||
move 10 from 9 to 1
|
||||
move 9 from 9 to 8
|
||||
move 13 from 4 to 3
|
||||
move 7 from 6 to 2
|
||||
move 2 from 8 to 5
|
||||
move 9 from 3 to 9
|
||||
move 8 from 9 to 8
|
||||
move 4 from 8 to 4
|
||||
move 1 from 7 to 5
|
||||
move 3 from 9 to 1
|
||||
move 7 from 2 to 1
|
||||
move 1 from 3 to 1
|
||||
move 1 from 3 to 6
|
||||
move 1 from 6 to 1
|
||||
move 2 from 3 to 6
|
||||
move 5 from 4 to 1
|
||||
move 1 from 6 to 1
|
||||
move 3 from 8 to 7
|
||||
move 8 from 8 to 4
|
||||
move 3 from 5 to 4
|
||||
move 1 from 6 to 7
|
||||
move 1 from 5 to 8
|
||||
move 4 from 5 to 2
|
||||
move 7 from 5 to 8
|
||||
move 3 from 2 to 7
|
||||
move 7 from 4 to 8
|
||||
move 11 from 8 to 4
|
||||
move 15 from 4 to 1
|
||||
move 25 from 1 to 6
|
||||
move 4 from 8 to 7
|
||||
move 1 from 2 to 4
|
||||
move 11 from 6 to 4
|
||||
move 12 from 6 to 3
|
||||
move 1 from 1 to 9
|
||||
move 1 from 9 to 8
|
||||
move 16 from 1 to 3
|
||||
move 1 from 8 to 7
|
||||
move 12 from 4 to 6
|
||||
move 9 from 6 to 5
|
||||
move 3 from 6 to 5
|
||||
move 6 from 7 to 5
|
||||
move 3 from 3 to 5
|
||||
move 2 from 6 to 3
|
||||
move 11 from 5 to 8
|
||||
move 2 from 8 to 3
|
||||
move 2 from 1 to 4
|
||||
move 7 from 3 to 1
|
||||
move 2 from 4 to 6
|
||||
move 2 from 6 to 2
|
||||
move 5 from 7 to 3
|
||||
move 1 from 1 to 6
|
||||
move 1 from 1 to 8
|
||||
move 2 from 2 to 5
|
||||
move 1 from 7 to 4
|
||||
move 1 from 1 to 2
|
||||
move 10 from 3 to 5
|
||||
move 11 from 3 to 6
|
||||
move 1 from 4 to 9
|
||||
move 1 from 9 to 4
|
||||
move 1 from 4 to 2
|
||||
move 2 from 5 to 9
|
||||
move 2 from 2 to 8
|
||||
move 2 from 1 to 6
|
||||
move 2 from 1 to 2
|
||||
move 2 from 3 to 6
|
||||
move 3 from 8 to 1
|
||||
move 3 from 1 to 4
|
||||
move 7 from 8 to 3
|
||||
move 2 from 9 to 5
|
||||
move 2 from 4 to 9
|
||||
move 7 from 5 to 6
|
||||
move 2 from 8 to 6
|
||||
move 1 from 4 to 8
|
||||
move 2 from 2 to 4
|
||||
move 21 from 6 to 3
|
||||
move 10 from 5 to 7
|
||||
move 7 from 7 to 6
|
||||
move 1 from 9 to 3
|
||||
move 1 from 4 to 9
|
||||
move 1 from 9 to 4
|
||||
move 1 from 8 to 4
|
||||
move 8 from 6 to 4
|
||||
move 1 from 4 to 5
|
||||
move 1 from 5 to 8
|
||||
move 4 from 3 to 6
|
||||
move 1 from 8 to 2
|
||||
move 1 from 4 to 2
|
||||
move 2 from 7 to 3
|
||||
move 2 from 2 to 7
|
||||
move 22 from 3 to 5
|
||||
move 4 from 6 to 2
|
||||
move 2 from 6 to 9
|
||||
move 7 from 3 to 9
|
||||
move 6 from 9 to 1
|
||||
move 18 from 5 to 3
|
||||
move 2 from 5 to 4
|
||||
move 20 from 3 to 5
|
||||
move 3 from 7 to 3
|
||||
move 5 from 1 to 2
|
||||
move 11 from 5 to 7
|
||||
move 1 from 1 to 7
|
||||
move 3 from 9 to 3
|
||||
move 16 from 5 to 8
|
||||
move 7 from 8 to 7
|
||||
move 1 from 9 to 2
|
||||
move 8 from 2 to 3
|
||||
move 2 from 2 to 4
|
||||
move 3 from 3 to 1
|
||||
move 9 from 3 to 8
|
||||
move 1 from 6 to 3
|
||||
move 9 from 7 to 3
|
||||
move 3 from 1 to 8
|
||||
move 1 from 7 to 9
|
||||
move 1 from 9 to 4
|
||||
move 1 from 7 to 5
|
||||
move 10 from 4 to 5
|
||||
move 2 from 4 to 2
|
||||
move 19 from 8 to 5
|
||||
move 1 from 8 to 3
|
||||
move 4 from 3 to 5
|
||||
move 2 from 4 to 8
|
||||
move 4 from 7 to 8
|
||||
move 4 from 3 to 9
|
||||
move 4 from 7 to 6
|
||||
move 2 from 2 to 5
|
||||
move 2 from 3 to 2
|
||||
move 6 from 8 to 7
|
||||
move 1 from 8 to 4
|
||||
move 2 from 6 to 4
|
||||
move 3 from 4 to 8
|
||||
move 3 from 9 to 2
|
||||
move 4 from 7 to 8
|
||||
move 28 from 5 to 8
|
||||
move 16 from 8 to 4
|
||||
move 11 from 8 to 4
|
||||
move 3 from 3 to 4
|
||||
move 7 from 5 to 8
|
||||
move 13 from 8 to 7
|
||||
move 1 from 5 to 6
|
||||
move 1 from 6 to 7
|
||||
move 1 from 9 to 2
|
||||
move 2 from 6 to 2
|
||||
move 12 from 4 to 9
|
||||
move 4 from 4 to 1
|
||||
move 2 from 9 to 8
|
||||
move 4 from 8 to 3
|
||||
move 3 from 4 to 5
|
||||
move 4 from 4 to 1
|
||||
move 4 from 4 to 7
|
||||
move 3 from 7 to 9
|
||||
move 5 from 9 to 7
|
||||
move 7 from 2 to 3
|
||||
move 1 from 5 to 7
|
||||
move 8 from 1 to 5
|
||||
move 1 from 2 to 4
|
||||
move 11 from 3 to 1
|
||||
move 10 from 5 to 3
|
||||
move 3 from 9 to 1
|
||||
move 3 from 9 to 6
|
||||
move 5 from 1 to 6
|
||||
move 7 from 6 to 9
|
||||
move 8 from 9 to 7
|
||||
move 9 from 3 to 4
|
||||
move 1 from 6 to 9
|
||||
move 8 from 7 to 1
|
||||
move 9 from 4 to 2
|
||||
move 2 from 1 to 6
|
||||
move 3 from 2 to 6
|
||||
move 4 from 4 to 6
|
||||
move 2 from 9 to 8
|
||||
move 2 from 1 to 2
|
||||
move 1 from 3 to 8
|
||||
move 2 from 8 to 4
|
||||
move 1 from 6 to 8
|
||||
move 11 from 1 to 6
|
||||
move 1 from 1 to 5
|
||||
move 3 from 2 to 9
|
||||
move 2 from 9 to 3
|
||||
move 1 from 1 to 7
|
||||
move 2 from 4 to 9
|
||||
move 4 from 2 to 9
|
||||
move 2 from 8 to 5
|
||||
move 10 from 6 to 1
|
||||
move 2 from 5 to 6
|
||||
move 5 from 9 to 8
|
||||
move 5 from 8 to 7
|
||||
move 1 from 2 to 1
|
||||
move 7 from 1 to 2
|
||||
move 2 from 9 to 4
|
||||
move 1 from 3 to 5
|
||||
move 15 from 7 to 2
|
||||
move 8 from 6 to 3
|
||||
move 2 from 4 to 3
|
||||
move 2 from 6 to 4
|
||||
move 4 from 7 to 1
|
||||
move 4 from 7 to 5
|
||||
move 1 from 6 to 4
|
||||
move 3 from 1 to 7
|
||||
move 5 from 7 to 6
|
||||
move 4 from 7 to 5
|
||||
move 18 from 2 to 4
|
||||
move 5 from 6 to 4
|
||||
move 4 from 1 to 2
|
||||
move 8 from 3 to 8
|
||||
move 2 from 8 to 4
|
||||
move 2 from 3 to 7
|
||||
move 1 from 5 to 7
|
||||
move 3 from 8 to 4
|
||||
move 2 from 7 to 2
|
||||
move 1 from 3 to 8
|
||||
move 9 from 2 to 6
|
||||
move 2 from 8 to 6
|
||||
move 1 from 7 to 3
|
||||
move 1 from 3 to 5
|
||||
move 3 from 6 to 8
|
||||
move 1 from 8 to 5
|
||||
move 1 from 5 to 9
|
||||
move 1 from 1 to 2
|
||||
move 5 from 4 to 6
|
||||
move 10 from 6 to 2
|
||||
move 5 from 2 to 6
|
||||
move 5 from 6 to 4
|
||||
move 1 from 6 to 3
|
||||
move 6 from 4 to 6
|
||||
move 3 from 2 to 6
|
||||
move 2 from 2 to 3
|
||||
move 11 from 4 to 6
|
||||
move 1 from 9 to 5
|
||||
move 4 from 6 to 7
|
||||
move 1 from 4 to 3
|
||||
move 12 from 4 to 3
|
||||
move 1 from 8 to 6
|
||||
move 9 from 5 to 7
|
||||
move 1 from 5 to 2
|
||||
move 1 from 8 to 5
|
||||
move 1 from 4 to 9
|
||||
move 9 from 7 to 9
|
||||
move 1 from 3 to 4
|
||||
move 2 from 3 to 6
|
||||
move 2 from 5 to 6
|
||||
move 2 from 8 to 5
|
||||
move 11 from 3 to 4
|
||||
move 2 from 3 to 1
|
||||
move 1 from 2 to 3
|
||||
move 1 from 3 to 8
|
||||
move 3 from 7 to 9
|
||||
move 5 from 4 to 2
|
||||
move 2 from 5 to 8
|
||||
move 6 from 4 to 2
|
||||
move 1 from 1 to 3
|
||||
move 12 from 9 to 1
|
||||
move 6 from 1 to 6
|
||||
move 1 from 8 to 4
|
||||
move 1 from 8 to 3
|
||||
move 5 from 2 to 7
|
||||
move 2 from 3 to 9
|
||||
move 5 from 7 to 1
|
||||
move 1 from 7 to 5
|
||||
move 2 from 9 to 1
|
||||
move 14 from 1 to 7
|
||||
move 2 from 4 to 7
|
||||
move 7 from 2 to 4
|
||||
move 1 from 2 to 1
|
||||
move 1 from 1 to 3
|
||||
move 1 from 5 to 4
|
||||
move 1 from 9 to 6
|
||||
move 16 from 6 to 5
|
||||
move 2 from 5 to 4
|
||||
move 12 from 6 to 8
|
||||
move 10 from 4 to 8
|
||||
move 9 from 7 to 3
|
||||
move 4 from 7 to 6
|
||||
move 11 from 5 to 8
|
||||
move 2 from 5 to 2
|
||||
move 14 from 8 to 9
|
||||
move 1 from 5 to 1
|
||||
move 3 from 9 to 4
|
||||
move 2 from 2 to 1
|
||||
move 7 from 8 to 3
|
||||
move 6 from 3 to 5
|
||||
move 8 from 9 to 8
|
||||
move 1 from 6 to 1
|
||||
move 1 from 4 to 2
|
||||
move 4 from 3 to 8
|
||||
move 1 from 7 to 2
|
||||
move 3 from 1 to 5
|
||||
move 2 from 5 to 7
|
||||
move 3 from 9 to 2
|
||||
move 1 from 1 to 8
|
||||
move 5 from 5 to 4
|
||||
move 2 from 7 to 8
|
||||
move 4 from 2 to 5
|
||||
move 1 from 2 to 4
|
||||
move 2 from 7 to 8
|
||||
move 4 from 6 to 2
|
||||
move 6 from 5 to 3
|
||||
move 1 from 6 to 5
|
||||
move 1 from 5 to 3
|
||||
move 1 from 3 to 8
|
||||
move 8 from 8 to 3
|
||||
move 9 from 8 to 5
|
||||
move 9 from 8 to 2
|
||||
move 2 from 8 to 9
|
||||
move 2 from 3 to 8
|
||||
move 5 from 5 to 8
|
||||
move 1 from 3 to 7
|
||||
move 2 from 9 to 5
|
||||
move 7 from 2 to 4
|
||||
move 14 from 4 to 6
|
||||
move 2 from 2 to 7
|
||||
move 1 from 7 to 3
|
||||
move 1 from 7 to 9
|
||||
move 3 from 5 to 2
|
||||
move 1 from 7 to 1
|
||||
move 3 from 2 to 4
|
||||
move 7 from 8 to 2
|
||||
move 3 from 6 to 1
|
||||
move 17 from 3 to 1
|
||||
move 2 from 8 to 3
|
||||
move 6 from 2 to 7
|
||||
move 2 from 7 to 9
|
||||
move 3 from 6 to 8
|
||||
move 2 from 8 to 6
|
||||
move 4 from 2 to 1
|
||||
move 3 from 4 to 7
|
||||
move 1 from 8 to 7
|
||||
move 1 from 8 to 9
|
||||
move 1 from 4 to 2
|
||||
move 3 from 5 to 7
|
||||
move 2 from 3 to 1
|
||||
move 2 from 3 to 5
|
||||
move 5 from 7 to 4
|
||||
move 5 from 7 to 3
|
||||
move 1 from 4 to 8
|
||||
move 3 from 3 to 1
|
||||
move 6 from 1 to 3
|
||||
move 1 from 7 to 5
|
||||
move 2 from 9 to 2
|
||||
move 3 from 5 to 8
|
||||
move 1 from 8 to 1
|
||||
move 8 from 3 to 5
|
||||
move 1 from 4 to 9
|
||||
move 3 from 6 to 5
|
||||
move 3 from 6 to 3
|
||||
move 2 from 3 to 7
|
||||
move 1 from 4 to 7
|
||||
move 3 from 6 to 4
|
||||
move 2 from 7 to 2
|
||||
move 1 from 7 to 8
|
||||
move 2 from 5 to 4
|
||||
move 1 from 6 to 1
|
||||
move 7 from 4 to 7
|
||||
move 7 from 5 to 2
|
||||
move 10 from 2 to 3
|
||||
move 3 from 2 to 6
|
||||
move 3 from 8 to 1
|
||||
move 1 from 8 to 7
|
||||
move 2 from 6 to 3
|
||||
move 1 from 6 to 9
|
||||
move 4 from 7 to 5
|
||||
move 16 from 1 to 5
|
||||
move 1 from 9 to 7
|
||||
move 3 from 7 to 6
|
||||
move 11 from 5 to 6
|
||||
move 2 from 7 to 9
|
||||
move 12 from 6 to 4
|
||||
move 2 from 6 to 9
|
||||
move 6 from 3 to 2
|
||||
move 1 from 5 to 7
|
||||
move 5 from 9 to 5
|
||||
move 1 from 9 to 6
|
||||
move 4 from 3 to 7
|
||||
move 1 from 4 to 2
|
||||
move 7 from 2 to 5
|
||||
move 3 from 5 to 2
|
||||
move 6 from 5 to 6
|
||||
move 3 from 2 to 6
|
||||
move 9 from 6 to 8
|
||||
move 5 from 5 to 9
|
||||
move 5 from 7 to 1
|
||||
move 4 from 1 to 9
|
||||
move 2 from 9 to 4
|
||||
move 1 from 6 to 7
|
||||
move 9 from 4 to 1
|
||||
move 7 from 5 to 9
|
||||
move 18 from 1 to 3
|
||||
move 9 from 9 to 5
|
||||
move 8 from 8 to 2
|
||||
move 1 from 2 to 5
|
||||
move 4 from 2 to 3
|
||||
move 4 from 9 to 6
|
||||
move 1 from 4 to 8
|
||||
move 2 from 5 to 7
|
||||
move 2 from 9 to 2
|
||||
move 10 from 3 to 9
|
||||
move 5 from 5 to 9
|
||||
move 1 from 7 to 2
|
||||
move 2 from 8 to 7
|
||||
move 2 from 3 to 5
|
||||
move 2 from 9 to 1
|
||||
move 2 from 7 to 3
|
||||
move 1 from 2 to 1
|
||||
move 5 from 5 to 8
|
||||
move 1 from 2 to 1
|
||||
move 15 from 3 to 6
|
||||
move 1 from 7 to 6
|
||||
move 10 from 6 to 5
|
||||
move 1 from 7 to 8
|
||||
move 4 from 1 to 6
|
||||
move 1 from 8 to 3
|
||||
move 2 from 1 to 5
|
||||
move 3 from 8 to 1
|
||||
move 1 from 4 to 6
|
||||
move 1 from 4 to 2
|
||||
move 4 from 9 to 7
|
||||
move 6 from 5 to 7
|
||||
move 3 from 1 to 9
|
||||
move 10 from 6 to 8
|
||||
move 2 from 1 to 3
|
||||
move 8 from 7 to 9
|
||||
move 1 from 9 to 6
|
||||
move 2 from 7 to 9
|
||||
move 3 from 3 to 5
|
||||
move 1 from 2 to 6
|
||||
move 2 from 6 to 5
|
||||
move 5 from 9 to 4
|
||||
move 4 from 8 to 2
|
||||
move 1 from 1 to 3
|
||||
move 4 from 5 to 9
|
||||
move 3 from 6 to 1
|
||||
move 2 from 1 to 5
|
||||
move 3 from 5 to 2
|
||||
move 8 from 8 to 3
|
||||
move 11 from 9 to 4
|
||||
move 13 from 4 to 8
|
||||
move 2 from 9 to 2
|
||||
move 2 from 3 to 1
|
||||
move 1 from 4 to 1
|
||||
move 1 from 3 to 8
|
||||
move 2 from 6 to 9
|
||||
move 7 from 8 to 1
|
||||
move 3 from 2 to 5
|
||||
move 7 from 2 to 5
|
||||
move 3 from 4 to 6
|
||||
move 4 from 9 to 2
|
||||
move 2 from 3 to 5
|
||||
move 9 from 5 to 6
|
||||
move 5 from 2 to 7
|
||||
move 2 from 9 to 2
|
||||
move 2 from 9 to 7
|
||||
move 12 from 6 to 8
|
||||
move 5 from 5 to 7
|
||||
move 1 from 9 to 8
|
||||
move 3 from 1 to 6
|
||||
move 5 from 5 to 8
|
||||
move 6 from 1 to 9
|
||||
move 2 from 1 to 5
|
||||
move 1 from 6 to 9
|
||||
move 5 from 9 to 7
|
||||
move 2 from 5 to 8
|
||||
move 11 from 7 to 6
|
||||
move 20 from 8 to 1
|
||||
move 2 from 9 to 8
|
||||
move 4 from 7 to 6
|
||||
move 6 from 8 to 3
|
||||
move 13 from 6 to 9
|
||||
move 4 from 3 to 2
|
||||
move 4 from 6 to 3
|
||||
move 2 from 3 to 6
|
||||
move 5 from 9 to 8
|
||||
move 2 from 7 to 1
|
||||
move 2 from 6 to 9
|
||||
move 6 from 8 to 3
|
||||
move 6 from 3 to 6
|
||||
move 5 from 2 to 9
|
||||
move 22 from 1 to 3
|
||||
move 3 from 2 to 1
|
||||
move 5 from 9 to 3
|
||||
move 1 from 1 to 6
|
||||
move 3 from 6 to 2
|
||||
move 1 from 2 to 4
|
||||
move 33 from 3 to 5
|
||||
move 1 from 8 to 7
|
||||
14
2022/days/05/src/main.rs
Normal file
14
2022/days/05/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
let _structured_input = utilities::parse(_input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {:?}", part1::part1(&_structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {:?}", part2::part2(&_structured_input));
|
||||
}
|
||||
48
2022/days/05/src/part1.rs
Normal file
48
2022/days/05/src/part1.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part1(input: &(WorkArea, Vec<Move>)) -> Vec<char> {
|
||||
let (mut work_area, moves) = input.to_owned();
|
||||
for r#move in moves {
|
||||
work_area.apply_move_cratemover9000(&r#move)
|
||||
}
|
||||
work_area
|
||||
.get_stacks()
|
||||
.iter()
|
||||
.map(|stack| stack.last().unwrap().to_owned())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = (
|
||||
WorkArea::new(vec![vec!['Z', 'N'], vec!['M', 'C', 'D'], vec!['P']]),
|
||||
vec![
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 1,
|
||||
},
|
||||
Move {
|
||||
to: 3,
|
||||
from: 1,
|
||||
number: 3,
|
||||
},
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 2,
|
||||
},
|
||||
Move {
|
||||
to: 2,
|
||||
from: 1,
|
||||
number: 1,
|
||||
},
|
||||
],
|
||||
);
|
||||
assert_eq!(part1(&input), vec!['C', 'M', 'Z']);
|
||||
}
|
||||
}
|
||||
48
2022/days/05/src/part2.rs
Normal file
48
2022/days/05/src/part2.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part2(input: &(WorkArea, Vec<Move>)) -> Vec<char> {
|
||||
let (mut work_area, moves) = input.to_owned();
|
||||
for r#move in moves {
|
||||
work_area.apply_move_cratemover9001(&r#move)
|
||||
}
|
||||
work_area
|
||||
.get_stacks()
|
||||
.iter()
|
||||
.map(|stack| stack.last().unwrap().to_owned())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = (
|
||||
WorkArea::new(vec![vec!['Z', 'N'], vec!['M', 'C', 'D'], vec!['P']]),
|
||||
vec![
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 1,
|
||||
},
|
||||
Move {
|
||||
to: 3,
|
||||
from: 1,
|
||||
number: 3,
|
||||
},
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 2,
|
||||
},
|
||||
Move {
|
||||
to: 2,
|
||||
from: 1,
|
||||
number: 1,
|
||||
},
|
||||
],
|
||||
);
|
||||
assert_eq!(part2(&input), vec!['M', 'C', 'D']);
|
||||
}
|
||||
}
|
||||
144
2022/days/05/src/utilities.rs
Normal file
144
2022/days/05/src/utilities.rs
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Move {
|
||||
pub to: usize,
|
||||
pub from: usize,
|
||||
pub number: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct WorkArea {
|
||||
stacks: Vec<Vec<char>>,
|
||||
}
|
||||
|
||||
impl WorkArea {
|
||||
pub fn new(stacks: Vec<Vec<char>>) -> Self {
|
||||
Self { stacks }
|
||||
}
|
||||
pub fn apply_move_cratemover9000(&mut self, action: &Move) {
|
||||
for _ in 0..action.number {
|
||||
let cargo = self.stacks.get_mut(action.from - 1).unwrap().pop().unwrap();
|
||||
self.stacks.get_mut(action.to - 1).unwrap().push(cargo);
|
||||
}
|
||||
}
|
||||
pub fn apply_move_cratemover9001(&mut self, action: &Move) {
|
||||
let mut crane_holder: Vec<char> = Vec::new();
|
||||
for _ in 0..action.number {
|
||||
let cargo = self.stacks.get_mut(action.from - 1).unwrap().pop().unwrap();
|
||||
crane_holder.push(cargo);
|
||||
}
|
||||
for cargo in crane_holder.iter().rev() {
|
||||
self.stacks.get_mut(action.to - 1).unwrap().push(*cargo);
|
||||
}
|
||||
}
|
||||
pub fn get_stacks(&self) -> &Vec<Vec<char>> {
|
||||
&self.stacks
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> (WorkArea, Vec<Move>) {
|
||||
let mut input = input.split("\n\n");
|
||||
let work_area = parse_work_area(input.next().unwrap());
|
||||
let moves = parse_moves(input.next().unwrap());
|
||||
(work_area, moves)
|
||||
}
|
||||
|
||||
pub fn parse_work_area(input: &str) -> WorkArea {
|
||||
//decode those bottom index numbers
|
||||
let index_row = input.lines().rev().next().unwrap();
|
||||
//some ascii math and array math to get the second to last char and convert it into a number.
|
||||
let index_max: usize = (index_row.as_bytes()[index_row.len() - 2] - b'0') as usize;
|
||||
//initalize the work area:
|
||||
let mut work_area: Vec<Vec<char>> = Vec::new();
|
||||
for _ in 0..index_max {
|
||||
work_area.push(Vec::new())
|
||||
}
|
||||
|
||||
//now parse the rest
|
||||
for line in input.lines().rev() {
|
||||
for (y, cargo_crate) in line.as_bytes().chunks(4).enumerate() {
|
||||
let cargo = cargo_crate[1] as char;
|
||||
//easiest way to filter out that last line is just to filter out digits.
|
||||
if cargo != ' ' && !cargo.is_ascii_digit() {
|
||||
work_area.get_mut(y).unwrap().push(cargo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WorkArea::new(work_area)
|
||||
}
|
||||
|
||||
pub fn parse_moves(input: &str) -> Vec<Move> {
|
||||
static PARSE_MOVES_REGEX: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"^move (\d+) from (\d+) to (\d+)$").unwrap());
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let cap = PARSE_MOVES_REGEX.captures(line).unwrap();
|
||||
Move {
|
||||
to: cap.get(3).unwrap().as_str().parse().unwrap(),
|
||||
from: cap.get(2).unwrap().as_str().parse().unwrap(),
|
||||
number: cap.get(1).unwrap().as_str().parse().unwrap(),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_work_area() {
|
||||
let input = " [D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3 ";
|
||||
assert_eq!(
|
||||
parse_work_area(input),
|
||||
WorkArea::new(vec![vec!['Z', 'N'], vec!['M', 'C', 'D'], vec!['P'],],)
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = " [D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
|
||||
move 1 from 2 to 1
|
||||
move 3 from 1 to 3
|
||||
move 2 from 2 to 1
|
||||
move 1 from 1 to 2";
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
(
|
||||
WorkArea::new(vec![vec!['Z', 'N'], vec!['M', 'C', 'D'], vec!['P'],],),
|
||||
vec![
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 1
|
||||
},
|
||||
Move {
|
||||
to: 3,
|
||||
from: 1,
|
||||
number: 3
|
||||
},
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 2
|
||||
},
|
||||
Move {
|
||||
to: 2,
|
||||
from: 1,
|
||||
number: 1
|
||||
},
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
6
2022/days/06/Cargo.toml
Normal file
6
2022/days/06/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "day06"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
1
2022/days/06/src/input.txt
Normal file
1
2022/days/06/src/input.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
bhzhtzzsczszsjjjzddfzdfzfjfzfbbnntnzznwzzvfvrrqmrmmdzzfqfhqhsqqpwpgwpppbtbnnstthmhrrsmmvsmmhjmjfmfsfjfnfnjjvcjjszjszjsszbznzbnzndzzmlldsdgdcddmqmfqqlcllbvllztzctzczdzttlmtlthtmhtmhmmszsllvzvdzzzsqzqbqccvfvcffzsfslfsllcglclwlvwvzzdsslggtzzgzdzmzddjljvvztttsgscsstztjztjztzvzwwthtftppnmpmmcpmmjlmjjjsfjsjppgcgwcggzffzwzbbmbrbprpqqpccfncfnffvcffsqqtzqzqwzwvzwwwbjbfbcbfblltnlnhhcthtvvzzfcfgfddlggbbshsggplglqqbrbggsvvzdvvlfvlvpvhhmggbrrnppjfjhffttfpffbdfbfvfqvvtcvvbvnnhbhhglgjgzzghhwrrtntrtwwfdfdmmcmtctftpptllzqllzflfrrgqgvgdvdfdbddprrrgccqvqnnmtmvmffpzzqggfbfnfwwqdqldqqlnqnttnbttrffnmmzwzjjtrjtrtmmqsmqmffqmfqfhhbthbhdhvdhvdvmvdmdhdshsqslldzztvvmzzdcccmbbhfhshrrrpsrrqqmdmmgdmmwdmdjdqqmcmttpgtgwgpwpprbrprhrsrllhsllprlplhppfzpffbhbccwdwbbrpbpvpqqmsspjssmbbmfmrmnrnwwgbwwbpwpjwwhqqgcqcvqccgffzpfftcffqlqjjznnlflhhlcczhzvhzhmzhmhfhnnqznntstwtggqjgjhggsvslltjlttfjjgffjzjwzzqzrrhlhzhbhphmhlmlzmzsmzmccvllgrrpbrbfbjfjttqjttdrdhhggqgddppqgpqgpgtptjptpllwccmwcmcpmcppdrrtstqqczqzvvlsltlddnvdvggcqqblqqsjqjttzhtzzszllqsqfqddqdbqddwqddfzzlczcscfsfpfdpdrpddsggcqchcfcpcssstwstwtggghvhqhzzqssjddwjwbjjsnjnfnwwglwwfnfhnnscsggzgjzzhzmmqfqsqwqrwqqqdtdcttzvvnbngbbcdbdggddnmddgzghhzgghwwbjbttlwlcctlccwwdhhrqrvrjjlglssgttpllwclwwtptwptwtvthtbhbzhbzhhrsrwwwnrwrfwfnwnhhnqqdjqjpqqwdwttzhttcdttvztzltzlzmzddrsdsfdsfftdfffmwffrjrffqrfqfsfqqqgqjggwzzrnnqfnqffdbfbtbbrpbrpbptpwttjmjjzrrhhqppdzdtdjttqwwtddjdzzmgzzhwwwdsdgssprsrgsgbbphhdpdwppnfppdqqwzzpbzzqwqpqsqhqdhqqtwwjnnmvmwvmmwwgjgzjjvcjcvcjcnjcncmmphmmvmwmwpwbbtbffhnhshgssgvgvrrbwbtbddqmqfqvvfqvqdvvdbvdbdcdfdlflmffrwwgmmttrztrrfrqrpqrrzjrjpjdpjprrnhhbhcbbcwwqlwwcssbddfrfjrfjfrjfjvvdmdtdzzlvzlzhzmhmhphchnnfqnffvccfpfbfpfqpprrmttzrzzjzmjmzjmmfvmmrzrqqdllgjlglcchssgllsbllrbrlrjlrrhhfwwsqwsstpssznzcznzqzssvtvtrrqwqvvtssgfsfhssljjnwjnjddjdggclcrrfsfhsstgtdtctfttvvsbvvbtbttcgcssjlslhlpljpppwzwnwdnngmgjjbzznwwdllrrfppshhvdhhldhdbbdbjbdjjrnjjzhzfhhsqqbqgmsbvnjsptlrsszlqfmgprvscphmqztbgtlrqvcgdzcptcqjncrdtfqnghnbmwwmcjgtjlbvqqzslgbbntrdfnvfjvfgcgngndjcspgwmpnsrqzzvzljbzlzzrwflrqqqmhsvqwbmdftnhwwzgqrlhddbbtwvbphljmstcjzvpjqwcnhlvpqvqdgvntgqzqwrlwbwvngwtqgrhznlzcvbwqmwncccjctrdzrmzjsvrmcfpjjcczhbvdfwhqvczggfmrspvprvvthvtqnsphpcsdmbrtbdqljvssdrhwjsrrlzprstpgqcbpmnpdgzgjttwcfrgjnsghmszlclgvmlsjrqfvflbnhwwphtvrnrbhdvdglcvgpzfsjpwwhtlvvdzthsrldfzhnlrblzsjjnwclqsqzgdbflhvpwcrtfbfbjcjttbjpvfgvfcswnqqwshbmqlscdzzwshfqwsvwnwzltbnrmzzhzvtwpzqcgwshpvzgtcmwrtrwctnpzbznnwqphnrgwljtrcwlqmvlndwrdrctztnmswslqmbjcmtlrmcpjvzccqszrnflqnqzttbhqlrhbmqdpscqvfgtdbnwjdcljwcbgbgjfzgrgpwqzqgbnrtpntfthhdbqmswvhnmwmszpghgjjzrbnbbfjblpstdfslmmmqfdcrhblqjqfphnldrvvfpnfrcvprjnqbzbspfpjtgqhnjbhnrwzcjvdbshhqpgrmzqpmjfmqwqvvdbddbsldwzzsrhnhsjjnvljrbwcnjrnjpmrrvfthftgptgtlpbgqffthflgftwcrqcqwqwrmrcmfrcqgmrnqjbscdcgrqlhjzthvzdgjbvpswflqcgsnlmgmvcsttsgmnqdtvwdvrndvfdcvrcwmqlmlhtrvthsndsrmnsfmdmfnpfmfhzjqmtcjzcrnsjdztztvgdtlrmbdmmstbfgpmmzthcslpvgrpgfljfgqlqhldfwvvvdvbzjtdtppbtrnqwsqztjrsjhtfrgmvsdngvsdzjgpwrldqpzdpvhljzpjvttwltdwcrhcbrgrvdrmpwvdwjchqsjfprbgtjtzggvgrgmlvvwqrjfprbbgjjqrtdfnrdffwbswbvqtqtfsrhsgrjhftqldhmcnmsnfflmdrzqdjmbqqgqsttdmtrrvfsjnccnhcpcvqtrzdjzrpwswmjvvgsgwvnmdgqwlctrlhqnsmczbwsjhmtgvdcgsndzlstcwchcztqqbtdwfvlljdvdlzljslgnzpmqvzfcvqhdzvgchffqgfwrnmwqzwgbzblpmvddlvnhglrhdnwzqwztzgjczjpwcjwmpnrnrhncfjfggrbphrjztwtfqmfjlwfhnqfftfghbnvtwgtmdzzrdrtmfrwhrrbhzmcllsgqzwzzqtgdggvzptvtdcpzmtmsfcfbjtzlbdrwhdbtdhhrgggmddnzsvjwgcdcqfppqwphfvlhmgqsznlhmgpnjvcvrwwppnphchgsrhjwjcpjggsrcwrvnllfgrmjltfzwhmbqwpwwzmrtlqcprrqztcgnghcbvzrbfptjmhtdcfhhffdbrswqpnpppnpqwtflrrmqgjzctmmvvvwzllbsfdvpqjtmvpjcpmjztscsgbdznfgcmtjzdqzwqrsvstnnvddcstzqjtnbsnlptpmbmfqmhppgnjrffqrtchgptbmwlwbwbcqqfngpbwtwdmlmdstmqwcwjtbwbbbhghgptmvhfmvqfvpwqzwnbjdhpwlgjgvprdjbnlzhnllssbpvzfzspwsscfpqtpdvtzvqncfrfrgddsdglqvpblmpcczlqfdmwzmgvrljhqtcglcvfhbdwhbttqqrjbqwhsrhrbjwmtqwqddvdggdwfsmnpbpvvgsqnvvrqntwmbzdnqpmmqtbnlsbmslpfmqjtgvbddhwvlvjtlrhqdpfnjwtbhwjwdrpgctbbrdqvbbnvgqwngrhqfvwzmlqtmhfqphnmczlbdpnbmpvwrsjbcnjnvcfgnsvlhpzdgdzgvfbgwdcrswznrggnghzssdwqvvlwftqhbnwdvghhvjlqqmcnqmvbwhrrnsswlwmwbsmpcpdzzgmcmqnzpvjpzqbwcsgdhqtqhcpbtqftvscmntsbdcbrndvlfhprpblzbjcpqhfljtvnvtgvrcgqbsgl
|
||||
14
2022/days/06/src/main.rs
Normal file
14
2022/days/06/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
// let _structured_input = utilities::parse(_input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(_input));
|
||||
}
|
||||
23
2022/days/06/src/part1.rs
Normal file
23
2022/days/06/src/part1.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part1(input: &str) -> usize {
|
||||
input
|
||||
.as_bytes()
|
||||
.windows(4)
|
||||
.position(|x| !find_dupes_stupid(x))
|
||||
.unwrap()+4
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
assert_eq!(part1("mjqjpqmgbljsphdztnvjfqwrcgsmlb"), 7);
|
||||
assert_eq!(part1("bvwbjplbgvbhsrlpgdmjqwftvncz"), 5);
|
||||
assert_eq!(part1("nppdvjthqldpwncqszvftbrmjlhg"), 6);
|
||||
assert_eq!(part1("nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg"), 10);
|
||||
assert_eq!(part1("zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw"), 11);
|
||||
}
|
||||
}
|
||||
23
2022/days/06/src/part2.rs
Normal file
23
2022/days/06/src/part2.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part2(input: &str) -> usize {
|
||||
input
|
||||
.as_bytes()
|
||||
.windows(14)
|
||||
.position(|x| !find_dupes_stupid(x))
|
||||
.unwrap()+14
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
assert_eq!(part2("mjqjpqmgbljsphdztnvjfqwrcgsmlb"), 19);
|
||||
assert_eq!(part2("bvwbjplbgvbhsrlpgdmjqwftvncz"), 23);
|
||||
assert_eq!(part2("nppdvjthqldpwncqszvftbrmjlhg"), 23);
|
||||
assert_eq!(part2("nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg"), 29);
|
||||
assert_eq!(part2("zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw"), 26);
|
||||
}
|
||||
}
|
||||
19
2022/days/06/src/utilities.rs
Normal file
19
2022/days/06/src/utilities.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
pub fn find_dupes_stupid<T: PartialEq>(slice: &[T]) -> bool {
|
||||
for i in 1..slice.len() {
|
||||
if slice[i..].contains(&slice[i - 1]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/* #[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = "test";
|
||||
assert_eq!(parse(input), 0);
|
||||
}
|
||||
} */
|
||||
11
2022/days/07/Cargo.toml
Normal file
11
2022/days/07/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "day07"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
once_cell.workspace = true
|
||||
regex.workspace = true
|
||||
thiserror.workspace = true
|
||||
305
2022/days/07/src/file_tree.rs
Normal file
305
2022/days/07/src/file_tree.rs
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
use std::{
|
||||
cell::RefCell,
|
||||
fmt::Display,
|
||||
ops::Deref,
|
||||
rc::{Rc, Weak},
|
||||
};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum FileTreeError {
|
||||
#[error("Directory operation on file")]
|
||||
IsFile,
|
||||
#[error("File operation on directory")]
|
||||
IsDir,
|
||||
#[error("File not found")]
|
||||
FileNotFound,
|
||||
#[error("File already exists")]
|
||||
FileAlreadyExists,
|
||||
}
|
||||
|
||||
type WeakNodeRef = Weak<RefCell<Node>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NodeRef(pub Rc<RefCell<Node>>);
|
||||
|
||||
impl Deref for NodeRef {
|
||||
type Target = Rc<RefCell<Node>>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Rc<RefCell<Node>>> for NodeRef {
|
||||
fn from(value: Rc<RefCell<Node>>) -> Self {
|
||||
NodeRef(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NodeRef> for Rc<RefCell<Node>> {
|
||||
fn from(value: NodeRef) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeRef {
|
||||
pub fn add_node(&mut self, mut node: Node) -> Result<NodeRef, FileTreeError> {
|
||||
node.set_parent(self);
|
||||
self.borrow_mut().add_children(node)
|
||||
}
|
||||
pub fn new_dir(name: String) -> NodeRef {
|
||||
NodeRef(Rc::new(RefCell::new(Node::new_dir(name))))
|
||||
}
|
||||
pub fn add_file(&mut self, name: String, size: usize) -> Result<NodeRef, FileTreeError> {
|
||||
self.add_node(Node::new_file(name, size))
|
||||
}
|
||||
pub fn add_dir(&mut self, name: String) -> Result<NodeRef, FileTreeError> {
|
||||
self.add_node(Node::new_dir(name))
|
||||
}
|
||||
pub fn get_all_dirs(&self) -> Vec<NodeRef> {
|
||||
let mut ret = Vec::new();
|
||||
match &self.borrow().contents {
|
||||
Contents::Size(_) => {}
|
||||
Contents::Children(c) => {
|
||||
ret.push(NodeRef(Rc::clone(self)));
|
||||
for node in c {
|
||||
ret.append(&mut node.get_all_dirs())
|
||||
}
|
||||
}
|
||||
};
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Node {
|
||||
pub name: String,
|
||||
parent: Option<WeakNodeRef>,
|
||||
contents: Contents,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
pub fn new_dir(name: String) -> Node {
|
||||
Node {
|
||||
name,
|
||||
parent: None,
|
||||
contents: Contents::Children(Vec::new()),
|
||||
}
|
||||
}
|
||||
pub fn new_file(name: String, size: usize) -> Node {
|
||||
Node {
|
||||
name,
|
||||
parent: None,
|
||||
contents: Contents::Size(size),
|
||||
}
|
||||
}
|
||||
pub fn get_total_size(&self) -> usize {
|
||||
match &self.contents {
|
||||
Contents::Size(s) => *s,
|
||||
Contents::Children(c) => c.iter().map(|f| f.borrow().get_total_size()).sum(),
|
||||
}
|
||||
}
|
||||
fn set_parent(&mut self, newparent: &NodeRef) {
|
||||
self.parent = Some(Rc::downgrade(newparent));
|
||||
}
|
||||
// does not set the parent, needs to be done on the NodeRef. (this is why this func isnt pub).
|
||||
// takes onwership of the node to make sure its not owned by another tree.
|
||||
fn add_children(&mut self, node: Node) -> Result<NodeRef, FileTreeError> {
|
||||
match self.contents {
|
||||
Contents::Size(_) => Err(FileTreeError::IsFile),
|
||||
Contents::Children(ref mut c) => {
|
||||
for file in c.iter() {
|
||||
if file.borrow().name == node.name {
|
||||
return Err(FileTreeError::FileAlreadyExists);
|
||||
}
|
||||
}
|
||||
let rc = Rc::new(RefCell::new(node));
|
||||
c.push(NodeRef(Rc::clone(&rc)));
|
||||
Ok(NodeRef(Rc::clone(&rc)))
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn remove_child_by_name(&mut self, name: &str) -> Result<(), FileTreeError> {
|
||||
match self.contents {
|
||||
Contents::Size(_) => Err(FileTreeError::IsFile),
|
||||
Contents::Children(ref mut c) => {
|
||||
for (i, file) in c.iter().enumerate() {
|
||||
if file.borrow().name == name {
|
||||
c.remove(i);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Err(FileTreeError::FileNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn get_parent(&self) -> Option<NodeRef> {
|
||||
match &self.parent {
|
||||
Some(w) => Some(NodeRef(w.clone().upgrade()?)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
pub fn get_size(&self) -> Result<usize, FileTreeError> {
|
||||
match self.contents {
|
||||
Contents::Size(s) => Ok(s),
|
||||
Contents::Children(_) => Err(FileTreeError::IsDir),
|
||||
}
|
||||
}
|
||||
pub fn set_size(&mut self, size: usize) -> Result<(), FileTreeError> {
|
||||
match self.contents {
|
||||
Contents::Size(ref mut s) => {
|
||||
*s = size;
|
||||
Ok(())
|
||||
}
|
||||
Contents::Children(_) => Err(FileTreeError::IsDir),
|
||||
}
|
||||
}
|
||||
pub fn get_children(&self) -> Result<impl Iterator<Item = NodeRef> + '_, FileTreeError> {
|
||||
match &self.contents {
|
||||
Contents::Size(_) => Err(FileTreeError::IsFile),
|
||||
Contents::Children(c) => Ok(c.iter().map(|n| NodeRef(Rc::clone(n)))),
|
||||
}
|
||||
}
|
||||
pub fn get_child_by_name(&self, name: &str) -> Result<NodeRef, FileTreeError> {
|
||||
match &self.contents {
|
||||
Contents::Size(_) => Err(FileTreeError::IsFile),
|
||||
Contents::Children(c) => {
|
||||
for file in c.iter() {
|
||||
if file.borrow().name == name {
|
||||
return Ok(NodeRef(Rc::clone(file)));
|
||||
}
|
||||
}
|
||||
Err(FileTreeError::FileNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Contents {
|
||||
Size(usize),
|
||||
Children(Vec<NodeRef>),
|
||||
}
|
||||
|
||||
impl Display for NodeRef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.borrow())
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Node {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "- {} {}", self.name, self.contents)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Contents {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Contents::Size(s) => write!(f, "(file, size = {})", s),
|
||||
Contents::Children(c) => {
|
||||
writeln!(f, "(dir)").expect("I have no clue how this could fail");
|
||||
for node in c {
|
||||
//padding
|
||||
for line in format!("{}", node).lines() {
|
||||
writeln!(f, " {line}")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_dir_construction() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = root.add_node(Node::new_dir("a".to_string())).unwrap();
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_dir("d".to_string()).unwrap();
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
assert_eq!(Rc::clone(root.deref()).borrow().get_total_size(), 48381165);
|
||||
println!("{}", root);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_size_calcs() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut dirs: Vec<NodeRef> = Vec::new();
|
||||
let mut cursor = root.add_dir("a".to_string()).unwrap();
|
||||
dirs.push(NodeRef(Rc::clone(&cursor)));
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
dirs.push(NodeRef(Rc::clone(&cursor)));
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_node(Node::new_dir("d".to_string())).unwrap();
|
||||
dirs.push(NodeRef(Rc::clone(&cursor)));
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
assert_eq!(Rc::clone(root.deref()).borrow().get_total_size(), 48381165);
|
||||
assert_eq!(Rc::clone(dirs[0].deref()).borrow().get_total_size(), 94853);
|
||||
assert_eq!(Rc::clone(dirs[1].deref()).borrow().get_total_size(), 584);
|
||||
assert_eq!(
|
||||
Rc::clone(dirs[2].deref()).borrow().get_total_size(),
|
||||
24933642
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_get_all_dirs() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = root.add_dir("a".to_string()).unwrap();
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_node(Node::new_dir("d".to_string())).unwrap();
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
let dirs = root.get_all_dirs();
|
||||
let sizes: Vec<usize> = dirs.iter().map(|d| d.borrow().get_total_size()).collect();
|
||||
println!("{:?}", sizes);
|
||||
assert_eq!(Rc::clone(root.deref()).borrow().get_total_size(), 48381165);
|
||||
assert_eq!(
|
||||
Rc::clone(dirs[0].deref()).borrow().get_total_size(),
|
||||
48381165
|
||||
);
|
||||
assert_eq!(Rc::clone(dirs[1].deref()).borrow().get_total_size(), 94853);
|
||||
assert_eq!(Rc::clone(dirs[2].deref()).borrow().get_total_size(), 584);
|
||||
assert_eq!(
|
||||
Rc::clone(dirs[3].deref()).borrow().get_total_size(),
|
||||
24933642
|
||||
);
|
||||
}
|
||||
}
|
||||
1030
2022/days/07/src/input.txt
Normal file
1030
2022/days/07/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
19
2022/days/07/src/main.rs
Normal file
19
2022/days/07/src/main.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::file_tree::NodeRef;
|
||||
|
||||
mod part1;
|
||||
mod part2;
|
||||
mod parser;
|
||||
mod file_tree;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parser::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(NodeRef(Rc::clone(&structured_input))));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(NodeRef(Rc::clone(&structured_input))));
|
||||
}
|
||||
262
2022/days/07/src/parser.rs
Normal file
262
2022/days/07/src/parser.rs
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::file_tree::*;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
||||
static IS_COMMAND_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^\$").unwrap());
|
||||
static PARSE_CD_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^\$ cd (\S*)$").unwrap());
|
||||
static PARSE_LS_ENTRY_REGEX: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"^([[:alnum:]]*) (\S*)$").unwrap());
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Command {
|
||||
CdRoot,
|
||||
CdUp,
|
||||
Cd(String),
|
||||
Ls(Vec<LsEntry>),
|
||||
}
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum LsEntry {
|
||||
Dir(String),
|
||||
File(ParseFile),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct ParseFile {
|
||||
size: usize,
|
||||
name: String,
|
||||
}
|
||||
|
||||
//parses a single line
|
||||
pub fn parse_to_commands(input: &str) -> Vec<Command> {
|
||||
let mut ret = Vec::new();
|
||||
let mut lines = input.lines().peekable();
|
||||
while lines.peek().is_some() {
|
||||
let line = lines.next().unwrap();
|
||||
if line == "$ ls" {
|
||||
ret.push(Command::Ls(parse_ls(&mut lines)));
|
||||
} else {
|
||||
let captures = PARSE_CD_REGEX
|
||||
.captures(line)
|
||||
.unwrap_or_else(|| panic!("invalid line {}", line));
|
||||
|
||||
ret.push(match &captures[1] {
|
||||
".." => Command::CdUp,
|
||||
"/" => Command::CdRoot,
|
||||
s => Command::Cd(s.to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn parse_ls(lines: &mut std::iter::Peekable<std::str::Lines<'_>>) -> Vec<LsEntry> {
|
||||
let mut ret: Vec<LsEntry> = Vec::new();
|
||||
while lines.peek().is_some() {
|
||||
// if the next line is a command, then we are at the end of the ls listing.
|
||||
let line = lines.peek().expect("no next line");
|
||||
if IS_COMMAND_REGEX.is_match(line) {
|
||||
break;
|
||||
}
|
||||
let captures = PARSE_LS_ENTRY_REGEX
|
||||
.captures(line)
|
||||
.unwrap_or_else(|| panic!("invalid line {}", line));
|
||||
ret.push(match &captures[1] {
|
||||
"dir" => LsEntry::Dir(captures[2].to_string()),
|
||||
_ => LsEntry::File(ParseFile {
|
||||
size: str::parse(&captures[1]).unwrap_or_else(|_| panic!("invalid line {}", line)),
|
||||
name: captures[2].to_string(),
|
||||
}),
|
||||
});
|
||||
lines.next();
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> NodeRef {
|
||||
commands_to_tree(parse_to_commands(input))
|
||||
}
|
||||
|
||||
pub fn commands_to_tree(input: Vec<Command>) -> NodeRef {
|
||||
let root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = NodeRef(Rc::clone(&root));
|
||||
for command in input {
|
||||
match command {
|
||||
Command::CdRoot => cursor = NodeRef(Rc::clone(&root)),
|
||||
Command::CdUp => cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap(),
|
||||
Command::Cd(name) => cursor = cursor.add_dir(name).unwrap(),
|
||||
Command::Ls(ls) => {
|
||||
for entry in ls {
|
||||
match entry {
|
||||
LsEntry::Dir(_) => {
|
||||
//dirs dont exist until you cd into them.
|
||||
}
|
||||
LsEntry::File(f) => {
|
||||
cursor.add_file(f.name, f.size).unwrap();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
root
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_to_commands() {
|
||||
let input = concat!(
|
||||
"$ cd /\n",
|
||||
"$ ls\n",
|
||||
"dir a\n",
|
||||
"14848514 b.txt\n",
|
||||
"8504156 c.dat\n",
|
||||
"dir d\n",
|
||||
"$ cd a\n",
|
||||
"$ ls\n",
|
||||
"dir e\n",
|
||||
"29116 f\n",
|
||||
"2557 g\n",
|
||||
"62596 h.lst\n",
|
||||
"$ cd e\n",
|
||||
"$ ls\n",
|
||||
"584 i\n",
|
||||
"$ cd ..\n",
|
||||
"$ cd ..\n",
|
||||
"$ cd d\n",
|
||||
"$ ls\n",
|
||||
"4060174 j\n",
|
||||
"8033020 d.log\n",
|
||||
"5626152 d.ext\n",
|
||||
"7214296 k"
|
||||
);
|
||||
assert_eq!(
|
||||
parse_to_commands(input),
|
||||
vec![
|
||||
Command::CdRoot,
|
||||
Command::Ls(vec![
|
||||
LsEntry::Dir(String::from("a")),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 14848514,
|
||||
name: String::from("b.txt")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 8504156,
|
||||
name: String::from("c.dat")
|
||||
}),
|
||||
LsEntry::Dir(String::from("d"))
|
||||
]),
|
||||
Command::Cd(String::from("a")),
|
||||
Command::Ls(vec![
|
||||
LsEntry::Dir(String::from("e")),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 29116,
|
||||
name: String::from("f")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 2557,
|
||||
name: String::from("g")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 62596,
|
||||
name: String::from("h.lst")
|
||||
}),
|
||||
]),
|
||||
Command::Cd(String::from("e")),
|
||||
Command::Ls(vec![LsEntry::File(ParseFile {
|
||||
size: 584,
|
||||
name: String::from("i")
|
||||
}),]),
|
||||
Command::CdUp,
|
||||
Command::CdUp,
|
||||
Command::Cd(String::from("d")),
|
||||
Command::Ls(vec![
|
||||
LsEntry::File(ParseFile {
|
||||
size: 4060174,
|
||||
name: String::from("j")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 8033020,
|
||||
name: String::from("d.log")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 5626152,
|
||||
name: String::from("d.ext")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 7214296,
|
||||
name: String::from("k")
|
||||
}),
|
||||
]),
|
||||
]
|
||||
)
|
||||
}
|
||||
#[test]
|
||||
fn test_commands_to_tree() {
|
||||
let input = vec![
|
||||
Command::CdRoot,
|
||||
Command::Ls(vec![
|
||||
LsEntry::Dir(String::from("a")),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 14848514,
|
||||
name: String::from("b.txt"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 8504156,
|
||||
name: String::from("c.dat"),
|
||||
}),
|
||||
LsEntry::Dir(String::from("d")),
|
||||
]),
|
||||
Command::Cd(String::from("a")),
|
||||
Command::Ls(vec![
|
||||
LsEntry::Dir(String::from("e")),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 29116,
|
||||
name: String::from("f"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 2557,
|
||||
name: String::from("g"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 62596,
|
||||
name: String::from("h.lst"),
|
||||
}),
|
||||
]),
|
||||
Command::Cd(String::from("e")),
|
||||
Command::Ls(vec![LsEntry::File(ParseFile {
|
||||
size: 584,
|
||||
name: String::from("i"),
|
||||
})]),
|
||||
Command::CdUp,
|
||||
Command::CdUp,
|
||||
Command::Cd(String::from("d")),
|
||||
Command::Ls(vec![
|
||||
LsEntry::File(ParseFile {
|
||||
size: 4060174,
|
||||
name: String::from("j"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 8033020,
|
||||
name: String::from("d.log"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 5626152,
|
||||
name: String::from("d.ext"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 7214296,
|
||||
name: String::from("k"),
|
||||
}),
|
||||
]),
|
||||
];
|
||||
let tree = commands_to_tree(input);
|
||||
println!("{}", tree);
|
||||
assert_eq!(Rc::clone(tree.deref()).borrow().get_total_size(), 48381165)
|
||||
}
|
||||
}
|
||||
37
2022/days/07/src/part1.rs
Normal file
37
2022/days/07/src/part1.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use crate::file_tree::*;
|
||||
|
||||
pub fn part1(input: NodeRef) -> usize {
|
||||
let dirs = input.get_all_dirs();
|
||||
dirs.iter()
|
||||
.map(|d| d.borrow().get_total_size())
|
||||
.filter(|s| *s <= 100000)
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{ops::Deref, rc::Rc};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = root.add_node(Node::new_dir("a".to_string())).unwrap();
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_dir("d".to_string()).unwrap();
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
assert_eq!(part1(root), 95437);
|
||||
}
|
||||
}
|
||||
44
2022/days/07/src/part2.rs
Normal file
44
2022/days/07/src/part2.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
use crate::file_tree::*;
|
||||
|
||||
const TOTAL_SPACE: usize = 70000000;
|
||||
const NEEDED_SPACE: usize = 30000000;
|
||||
|
||||
pub fn part2(input: NodeRef) -> usize {
|
||||
let used_space = input.borrow().get_total_size();
|
||||
let unused_space = TOTAL_SPACE - used_space;
|
||||
let space_to_free = NEEDED_SPACE - unused_space;
|
||||
let dirs = input.get_all_dirs();
|
||||
dirs.iter()
|
||||
.map(|d| d.borrow().get_total_size())
|
||||
.filter(|s| *s >= space_to_free)
|
||||
.min()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{ops::Deref, rc::Rc};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = root.add_node(Node::new_dir("a".to_string())).unwrap();
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_dir("d".to_string()).unwrap();
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
assert_eq!(part2(root), 24933642);
|
||||
}
|
||||
}
|
||||
6
2022/days/08/Cargo.toml
Normal file
6
2022/days/08/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "day08"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
99
2022/days/08/src/input.txt
Normal file
99
2022/days/08/src/input.txt
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
002100030222341303232115221524311502200403234452204125251345024423544443305142410110142101223120110
|
||||
102030322341143330244233013052025453422005415304655426206452251310214055314024034341233110302320003
|
||||
003012203404011430120134554314552441635001641050211406204621114102021543144514102510421243314102033
|
||||
330313423002034140035001210441156554545625042262651356556544202500446121455112434243313013430141203
|
||||
331203121131230002055113430244610062654034520106363462155201210355601153542301323442223310134324300
|
||||
232201231021003254355411402310326206625011564114125202263504451451212600155351424154310240411213431
|
||||
033033333301011523544023206136145505304224325606020360006206455564513553512054354124523232201230441
|
||||
132201032234334044251334220345360402456541662253556375754662323265201641514121105025300453041111234
|
||||
314322341322104402235020206565044225363527617767574524475421763504341061551154250344125514014234344
|
||||
101323043023430543342440532324326413655657527215661116623455613664321005134300223542510253102211310
|
||||
320404242514122111525043444530625417656773117247512712444315767422412130351505513231104322032421303
|
||||
221204123205133142044056245654205231734371546616753217321556472223654044043612554152141554333102034
|
||||
340310155225452152216635634352712541366312326272262143522347111166646736001360102010220214000133002
|
||||
012404003515002416422500163244271366252711531615333437352461454777311142132000140205630042305222013
|
||||
332434552302203445503543424523327464362526657251687634745536521746523154717531643250132300541053000
|
||||
020130312425316362611130462217125425435545265467725256332777233137141524314631100051153314314343032
|
||||
112115124512002346011342433146124542356845483862756322785545283652723747276776403131622540014001524
|
||||
332354013101003031053022245431274627654677343638672643442563448782737464337546541546630431125021330
|
||||
220315320142064161406534365262377268373743527784575246325564676238816733767331345114363612344051535
|
||||
102041153526000601402325625766534543527882476653366727573448727775677146365732431425225562043130034
|
||||
350054114310533002426654125166575285757827422257872378766383267543484865317252532765440216543555512
|
||||
222440404353016144747347457368562668586285847553578732435887584463446862116134751240360645225435344
|
||||
554234546163262630313431762248876668663352436888374587856263343842526635237314231451062036605442520
|
||||
525531324662660356256614344438373575732699988366775989976447384338336827686445577222030363631240512
|
||||
055541261042533424177375756738443482846986979788978997559377679255463858237757327464422026230510130
|
||||
514123221240250442457744728347386637684953574546455344754548333793233865436751231314653541223102202
|
||||
355454250661114645144551785724753237378345375493453967559796675839837444334776625552412552302431302
|
||||
202445234333206767744653874724276586973668878949653473947686567565487325864733735677672241416513452
|
||||
445415223211061633767433865252483574744685974593334963668983745643354885658423263536531213102544202
|
||||
201405464251164654177385783224666473975674643767946648464678958969336335638578275154116223152222102
|
||||
401423140356441654745572266848965593553995667644648964747884544439493545472454437715336645303346422
|
||||
154440323240741427732867467564957336394985859766644495658985963583496399736552632162756445212536404
|
||||
441663663062661372122867364584655388977474857585778686889578799644949733463423826715534215154065204
|
||||
422036122016243651174663588693898583374968974778579585977478599643389537573534354622377452555411315
|
||||
430412403362272513348763673566578945645997454758694486758844958569786758359475575577532661126532300
|
||||
503653020441267422765353469867998339764449596776968996449777464644846938866332635583727771665263026
|
||||
006252631541331635768754753357384754988659585857956567666645975599653466655333342485345762600032403
|
||||
215205542775713732868842389885585646884858449858579777975997584997463698339932263363162431251615251
|
||||
342224450731115175762626546538955447796468885776778879697695699945446388444478355347827635732006646
|
||||
045011110226211633623658548365544498466468766878699597655897586488555435934935526883851537736604133
|
||||
440352212243431376382869634434568447654566895897796875679759667598898849334873844583742271767024403
|
||||
566632367121414762272448784755746799985759966559657989697977677955455754549393784586875275341562621
|
||||
004131167135757426882464486773699786789959957795985595559587775554479945637849747667752242212324244
|
||||
022411031432724262533554794664597446479869568767598899669969588984864457535986725263473577457413134
|
||||
036415005331162527346577487593798458668976888776888766856699598847776567686579476836656723623111342
|
||||
504001302331545267684439554776894957999788577876688969865558955547965687556849786463457244355044511
|
||||
464266074264126575276833864784546697885788878967966988678696686685576789843676844576623242451411411
|
||||
660130573642326366362654785549676574587876888769689696798799988678648554635745724364273772474666502
|
||||
413511521313437652422664948645649566979966676679778669968777776786958464356797545247763267365643645
|
||||
455033174473274564484285387995879595555686569997977698868769855686564847593489668858847744131410225
|
||||
560316675532344635443349663994499869866598568889798868967976679655597494679336978524332246567265361
|
||||
121053163342234352453837754569968465557968697766766888969966667796479457384444468264837376474515455
|
||||
604062313527642634768255846899648545559665886668966887999959659769978495794795825775373713613231451
|
||||
041031112622754332842439776736966994677888699898679988967779696758849589365579766676242256227420364
|
||||
630161363126476778455475799658545955598576568877768698668579988799596866465635488284555252726211044
|
||||
455563641427127283364758796475975894658677688789777769876667978747955677573575525588444241765111511
|
||||
256420063532645225542863884958844496596759999769769687678888788875449888945958948378756476127155054
|
||||
523256165217547362636325547686549767698957967985968987897777685866576744344388256886854362647342110
|
||||
205224606764556763544234874676659474468968576879668558856675855668779847849738247387744421321145610
|
||||
022651355615653552468486676459694744747575877656886776677858584988944678787576556747724125467333305
|
||||
526313424324717126486746644643397589664468865599858886996669788566489473798387676766873216657521426
|
||||
426530404522411762572567697375959747975669667958685679878659587764977658398697353283563215312244014
|
||||
023510245741131775436864579684699874979976567776557765866775469587757498544476554753722641656303654
|
||||
211341433442225414565332887899363678699495567888998675657659688744458493387343842346747477252626250
|
||||
406543152154335614758277748595836896786654948759999978569588555764838686653647362854723163226456101
|
||||
333640633617315535456525364849458558744656899855554897897568844446533866457545654847562377442214226
|
||||
040003053246534354438748723933365934878485997458955574785966996653353969666867276761661111124104550
|
||||
405602516206264365157378627495546935658594587869579958969686766986836687348285865231616336232000100
|
||||
304131030254233641578272475868953446545577766644956989679964489688554398956223433417637732661500540
|
||||
131164662225325441733366324345477954639475997658684766465487974699579665344326248136151472051130445
|
||||
452312154206174654138684277376889449945746954689646875777596486949365968888456226732332263263420000
|
||||
003010154551246223274282454345355673349967689986885795449989359633496728553885221437611730454554455
|
||||
131435126460017635544785754344874379695379366384573934357795398633967475353836864461424146264354142
|
||||
350154544045013352533173566257757787385448697484997454578735937499665628425542376452563635450224022
|
||||
302420224365163651765264446875287359533637498445639443969586466433384346337722662774436566624454214
|
||||
415242456321105173655733744886343826548944666338683876383973497998744488687446541256724244661531431
|
||||
155303206134314124372553618623857237346567857564464797593393675563536467777317174625640132203003240
|
||||
335521544652523624641575451785635352333587957647598535633948867838652636686573137515062356442045153
|
||||
235314500244636615342325346277256685653838226755493858683465683736283367654226655456541546644313125
|
||||
252520511531061305614364671212856473625642477732845278766573642425286572562373137446456005011330433
|
||||
241525455120116046543737642325543677623243884242534423327827446383376441727657314343125403632434002
|
||||
301045223551220356167117621755325772252845222546246588464784874685774676163655131632622146412415515
|
||||
011150133311336614251435416453632383454327534367288242328746537673543714263674263262001132354544412
|
||||
314104033000306256531666256433553535833538337463847277453476563227672715617272601302551120422305504
|
||||
104211442013141664402363645617163435245556228235337864656673626354151416721375243323635625100210424
|
||||
413422313502535362615054171511431775335574748526574728747453724472157632635263350024552502052340024
|
||||
131225301023304456424150404525765416565572272321835377167235317312551645334432406536160545434122120
|
||||
342131052232413325301451041516716541737346252413667115612642227312572433104525003114240240141232002
|
||||
244421101354005430232434420344323273421374225635551363463245561271743411452116466311034334101231020
|
||||
232404402304311415164151401553463731147111147752141732625152553615361046133341313265525232544143442
|
||||
201321033520133414312301326330253041267251614477322566645472656414545035321106361434351501123314104
|
||||
211232034442524242313453325046331353174352335422752364775746537513333534355120322320404054014303124
|
||||
224032233240430510135541652065052415154147565656231651653327511443424113100543020223335130010141400
|
||||
004110101133543440511523265424013341433043655022512172622140322434116104552043413352211021312421433
|
||||
000304433232402410151205333526613043463556021413402141634154404530112303306244402221312522221004042
|
||||
200204441020135232033032541516232550445221141520665016336536052063115335040344025054213324400312303
|
||||
300211022440310123055510053251505226452265556365100101014044645236505213550201425252404100302413231
|
||||
310312413210032422053242024243343060135340422313312403505631104430120233112324204414021331012401232
|
||||
132020341330304022053503522313342026211133610000020554213662244142551253124302245242110111033101203
|
||||
16
2022/days/08/src/main.rs
Normal file
16
2022/days/08/src/main.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
type StructuredInput = Vec<Vec<u8>>;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = utilities::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
85
2022/days/08/src/part1.rs
Normal file
85
2022/days/08/src/part1.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
use crate::StructuredInput;
|
||||
|
||||
pub fn part1(input: &StructuredInput) -> usize {
|
||||
let mut acc: usize = 0;
|
||||
for y in 0..input.len(){
|
||||
for x in 0..input[0].len(){
|
||||
if is_visible(x, y, input){
|
||||
acc+=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
acc
|
||||
}
|
||||
|
||||
fn is_visible(x: usize, y: usize, input: &StructuredInput) -> bool {
|
||||
is_visible_north(x, y, input)
|
||||
|| is_visible_east(x, y, input)
|
||||
|| is_visible_south(x, y, input)
|
||||
|| is_visible_west(x, y, input)
|
||||
}
|
||||
fn is_visible_north(x: usize, y: usize, input: &StructuredInput) -> bool {
|
||||
if y == 0 {
|
||||
return true;
|
||||
};
|
||||
let hight = input[y][x];
|
||||
for y in 0..y {
|
||||
if input[y][x] >= hight {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
fn is_visible_east(x: usize, y: usize, input: &StructuredInput) -> bool {
|
||||
if x == input[0].len() {
|
||||
return true;
|
||||
}
|
||||
let hight = input[y][x];
|
||||
for x in (x + 1)..input[0].len() {
|
||||
if input[y][x] >= hight {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
fn is_visible_south(x: usize, y: usize, input: &StructuredInput) -> bool {
|
||||
if y == input.len() {
|
||||
return true;
|
||||
};
|
||||
let hight = input[y][x];
|
||||
for y in (y + 1)..input.len() {
|
||||
if input[y][x] >= hight {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
fn is_visible_west(x: usize, y: usize, input: &StructuredInput) -> bool {
|
||||
if x == input[0].len() {
|
||||
return true;
|
||||
}
|
||||
let hight = input[y][x];
|
||||
for x in 0..x {
|
||||
if input[y][x] >= hight {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
vec![3, 0, 3, 7, 3],
|
||||
vec![2, 5, 5, 1, 2],
|
||||
vec![6, 5, 3, 3, 2],
|
||||
vec![3, 3, 5, 4, 9],
|
||||
vec![3, 5, 3, 9, 0],
|
||||
];
|
||||
assert_eq!(part1(&input), 21);
|
||||
}
|
||||
}
|
||||
109
2022/days/08/src/part2.rs
Normal file
109
2022/days/08/src/part2.rs
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
use crate::StructuredInput;
|
||||
|
||||
pub fn part2(input: &StructuredInput) -> usize {
|
||||
let mut max: usize = 0;
|
||||
for y in 0..input.len() {
|
||||
for x in 0..input[0].len() {
|
||||
let tree_score = tree_score(x, y, input);
|
||||
if max < tree_score{
|
||||
max = tree_score;
|
||||
println!("found new max with score {} at {}, {}", tree_score, x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
max
|
||||
}
|
||||
fn tree_score(x: usize, y: usize, input: &StructuredInput) -> usize {
|
||||
trees_visible_north(x, y, input)
|
||||
* trees_visible_east(x, y, input)
|
||||
* trees_visible_south(x, y, input)
|
||||
* trees_visible_west(x, y, input)
|
||||
}
|
||||
fn trees_visible_north(x: usize, y: usize, input: &StructuredInput) -> usize {
|
||||
if y == 0 {
|
||||
return 0;
|
||||
};
|
||||
let hight = input[y][x];
|
||||
let mut trees: usize = 0;
|
||||
for y in (0..y).rev() {
|
||||
trees += 1;
|
||||
if input[y][x] >= hight {
|
||||
break
|
||||
}
|
||||
}
|
||||
trees
|
||||
}
|
||||
fn trees_visible_east(x: usize, y: usize, input: &StructuredInput) -> usize {
|
||||
if x == input[0].len() {
|
||||
return 0;
|
||||
}
|
||||
let hight = input[y][x];
|
||||
let mut trees: usize = 0;
|
||||
for x in (x + 1)..input[0].len() {
|
||||
trees += 1;
|
||||
if input[y][x] >= hight {
|
||||
break
|
||||
}
|
||||
}
|
||||
trees
|
||||
}
|
||||
fn trees_visible_south(x: usize, y: usize, input: &StructuredInput) -> usize {
|
||||
if y == input.len() {
|
||||
return 0;
|
||||
};
|
||||
let hight = input[y][x];
|
||||
let mut trees: usize = 0;
|
||||
for y in (y + 1)..input.len() {
|
||||
trees += 1;
|
||||
if input[y][x] >= hight {
|
||||
break
|
||||
}
|
||||
}
|
||||
trees
|
||||
}
|
||||
fn trees_visible_west(x: usize, y: usize, input: &StructuredInput) -> usize {
|
||||
if x == input[0].len() {
|
||||
return 0;
|
||||
}
|
||||
let hight = input[y][x];
|
||||
let mut trees: usize = 0;
|
||||
for x in (0..x).rev() {
|
||||
trees += 1;
|
||||
if input[y][x] >= hight {
|
||||
break
|
||||
}
|
||||
}
|
||||
trees
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = vec![
|
||||
vec![3, 0, 3, 7, 3],
|
||||
vec![2, 5, 5, 1, 2],
|
||||
vec![6, 5, 3, 3, 2],
|
||||
vec![3, 3, 5, 4, 9],
|
||||
vec![3, 5, 3, 9, 0],
|
||||
];
|
||||
assert_eq!(part2(&input), 8);
|
||||
}
|
||||
#[test]
|
||||
fn test_trees_visible() {
|
||||
let input = vec![
|
||||
vec![3, 0, 3, 7, 3],
|
||||
vec![2, 5, 5, 1, 2],
|
||||
vec![6, 5, 3, 3, 2],
|
||||
vec![3, 3, 5, 4, 9],
|
||||
vec![3, 5, 3, 9, 0],
|
||||
];
|
||||
assert_eq!(trees_visible_north(2, 3, &input), 2);
|
||||
assert_eq!(trees_visible_east(2, 3, &input), 2);
|
||||
assert_eq!(trees_visible_south(2, 3, &input), 1);
|
||||
assert_eq!(trees_visible_west(2, 3, &input), 2);
|
||||
assert_eq!(tree_score(2, 3, &input), 8);
|
||||
}
|
||||
}
|
||||
26
2022/days/08/src/utilities.rs
Normal file
26
2022/days/08/src/utilities.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
pub fn parse(input: &str) -> Vec<Vec<u8>> {
|
||||
input
|
||||
.lines()
|
||||
.map(|l| l.chars().map(|c| c.to_digit(10).unwrap() as u8).collect())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!("30373\n", "25512\n", "65332\n", "33549\n", "35390\n",);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
vec![3, 0, 3, 7, 3],
|
||||
vec![2, 5, 5, 1, 2],
|
||||
vec![6, 5, 3, 3, 2],
|
||||
vec![3, 3, 5, 4, 9],
|
||||
vec![3, 5, 3, 9, 0]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
11
2022/days/09/Cargo.toml
Normal file
11
2022/days/09/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "day09"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
regex.workspace = true
|
||||
once_cell.workspace = true
|
||||
2000
2022/days/09/src/input.txt
Normal file
2000
2022/days/09/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
15
2022/days/09/src/main.rs
Normal file
15
2022/days/09/src/main.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
mod rope;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
75
2022/days/09/src/parse.rs
Normal file
75
2022/days/09/src/parse.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Direction {
|
||||
Up,
|
||||
Right,
|
||||
Down,
|
||||
Left,
|
||||
}
|
||||
|
||||
static PARSE_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^([URDL]) (\d+)$").unwrap());
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Direction> {
|
||||
let mut ret = Vec::new();
|
||||
for line in input.lines() {
|
||||
let captures = PARSE_REGEX
|
||||
.captures(line)
|
||||
.unwrap_or_else(|| panic!("invalid line {}", line));
|
||||
let dir = match &captures[1] {
|
||||
"U" => Direction::Up,
|
||||
"R" => Direction::Right,
|
||||
"D" => Direction::Down,
|
||||
"L" => Direction::Left,
|
||||
_ => panic!("invalid direction char"),
|
||||
};
|
||||
for _ in 0..captures[2]
|
||||
.parse()
|
||||
.unwrap_or_else(|_| panic!("invalid line {}", line))
|
||||
{
|
||||
ret.push(dir)
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input =
|
||||
concat!("R 4\n", "U 4\n", "L 3\n", "D 1\n", "R 4\n", "D 1\n", "L 5\n", "R 2\n",);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Down,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Down,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
53
2022/days/09/src/part1.rs
Normal file
53
2022/days/09/src/part1.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use aoc_libs::points::Point;
|
||||
|
||||
use crate::parse::Direction;
|
||||
use crate::rope::Rope;
|
||||
|
||||
pub fn part1(input: &Vec<Direction>) -> usize {
|
||||
let mut visited: HashSet<Point> = HashSet::new();
|
||||
let mut rope: Rope<2> = Rope::new();
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
for direction in input {
|
||||
rope.update_rope(direction);
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
}
|
||||
visited.len()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Down,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Down,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
];
|
||||
assert_eq!(part1(&input), 13);
|
||||
}
|
||||
}
|
||||
31
2022/days/09/src/part2.rs
Normal file
31
2022/days/09/src/part2.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use aoc_libs::points::Point;
|
||||
|
||||
use crate::{parse::Direction, rope::Rope};
|
||||
|
||||
pub fn part2(input: &Vec<Direction>) -> usize {
|
||||
let mut visited: HashSet<Point> = HashSet::new();
|
||||
let mut rope: Rope<10> = Rope::new();
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
for direction in input {
|
||||
rope.update_rope(direction);
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
}
|
||||
visited.len()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::parse::parse;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = parse(concat!(
|
||||
"R 5\n", "U 8\n", "L 8\n", "D 3\n", "R 17\n", "D 10\n", "L 25\n", "U 20\n",
|
||||
));
|
||||
assert_eq!(part2(&input), 36);
|
||||
}
|
||||
}
|
||||
160
2022/days/09/src/rope.rs
Normal file
160
2022/days/09/src/rope.rs
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use crate::parse::Direction;
|
||||
use aoc_libs::points::{Point, UPoint};
|
||||
|
||||
// L is the length of the rope in segments.
|
||||
#[derive(Debug)]
|
||||
pub struct Rope<const L: usize> {
|
||||
segments: [Point; L],
|
||||
}
|
||||
|
||||
impl<const L: usize> Rope<L> {
|
||||
pub fn new() -> Rope<L> {
|
||||
Rope {
|
||||
segments: [Point::default(); L],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_rope(&mut self, direction: &Direction) {
|
||||
self.segments[0] += match direction {
|
||||
Direction::Up => Point { x: 0, y: 1 },
|
||||
Direction::Right => Point { x: 1, y: 0 },
|
||||
Direction::Down => Point { x: 0, y: -1 },
|
||||
Direction::Left => Point { x: -1, y: 0 },
|
||||
};
|
||||
for segment in 1..self.segments.len() {
|
||||
self.segments[segment] += Rope::<L>::update_single_segment_pair(
|
||||
&self.segments[segment - 1],
|
||||
&self.segments[segment],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_tail_pos(&self) -> &Point {
|
||||
&self.segments[self.segments.len() - 1]
|
||||
}
|
||||
|
||||
// the rope segment will not move if the segment ahead of it is only at most one away, and will
|
||||
// move with the following rules if it is 2 away: It moves straight towards the head if the
|
||||
// head is directly up/down/left/right, and diagonally towards it if its not straight
|
||||
// up/down/left/right.
|
||||
fn update_single_segment_pair(head: &Point, tail: &Point) -> Point {
|
||||
let delta = *head - *tail;
|
||||
if delta.x.abs() > 2 || delta.y.abs() > 2 {
|
||||
panic!("invalid delta ({}, {})", delta.y, delta.x)
|
||||
}
|
||||
match (delta.x, delta.y) {
|
||||
(0, 2) => Point { x: 0, y: 1 },
|
||||
(2, 0) => Point { x: 1, y: 0 },
|
||||
(0, -2) => Point { x: 0, y: -1 },
|
||||
(-2, 0) => Point { x: -1, y: 0 },
|
||||
(1, 2) | (2, 2) | (2, 1) => Point { x: 1, y: 1 },
|
||||
(2, -1) | (2, -2) | (1, -2) => Point { x: 1, y: -1 },
|
||||
(-1, -2) | (-2, -2) | (-2, -1) => Point { x: -1, y: -1 },
|
||||
(-2, 1) | (-2, 2) | (-1, 2) => Point { x: -1, y: 1 },
|
||||
_ => Point { x: 0, y: 0 },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<const L: usize> Display for Rope<{ L }> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let grid_size = (self.segments.len() * 2) - 1;
|
||||
let zero_point = UPoint {
|
||||
x: self.segments.len() - 1,
|
||||
y: self.segments.len() - 1,
|
||||
};
|
||||
|
||||
let mut grid: Vec<Vec<char>> = Vec::with_capacity(grid_size);
|
||||
for y in 0..grid_size {
|
||||
grid.push(Vec::with_capacity(grid_size));
|
||||
for _ in 0..grid_size {
|
||||
grid[y].push('.')
|
||||
}
|
||||
}
|
||||
|
||||
for segment in self.segments.iter().skip(1) {
|
||||
let delta = *segment - self.segments[0];
|
||||
let upoint = delta.to_upoint(&zero_point).unwrap();
|
||||
grid[upoint.y][upoint.x] = 'T'
|
||||
}
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
"head is at {}, {}",
|
||||
self.segments[0].x, self.segments[0].y
|
||||
)?;
|
||||
let upoint = Point { x: 0, y: 0 }.to_upoint(&zero_point).unwrap();
|
||||
grid[upoint.y][upoint.x] = 'H';
|
||||
|
||||
for line in grid {
|
||||
let mut writeline = "".to_string();
|
||||
for char in line {
|
||||
writeline.push(char)
|
||||
}
|
||||
writeln!(f, "{}", writeline)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_single_segment() {
|
||||
let input = [
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Down,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Down,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
];
|
||||
let mut visited: HashSet<Point> = HashSet::new();
|
||||
let mut rope: Rope<2> = Rope::new();
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
println!("{}", rope);
|
||||
for direction in input {
|
||||
rope.update_rope(&direction);
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
println!("{}", rope);
|
||||
}
|
||||
// let mut graph = [
|
||||
// ['.', '.', '.', '.', '.', '.'],
|
||||
// ['.', '.', '.', '.', '.', '.'],
|
||||
// ['.', '.', '.', '.', '.', '.'],
|
||||
// ['.', '.', '.', '.', '.', '.'],
|
||||
// ['s', '.', '.', '.', '.', '.'],
|
||||
// ];
|
||||
// for point in &visited {
|
||||
// graph[4 - point.y as usize][point.x as usize] = '#';
|
||||
// }
|
||||
// for line in graph {
|
||||
// println!("{:?}", line)
|
||||
// }
|
||||
assert_eq!(visited.len(), 13)
|
||||
}
|
||||
}
|
||||
10
2022/days/10/Cargo.toml
Normal file
10
2022/days/10/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day10"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
nom.workspace = true
|
||||
118
2022/days/10/src/crt.rs
Normal file
118
2022/days/10/src/crt.rs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use crate::machine::Machine;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Crt {
|
||||
pub screen: [[bool; 40]; 6],
|
||||
}
|
||||
|
||||
impl Crt {
|
||||
pub fn draw_pixel(&mut self, sprite_pos: i32, cycle: usize) {
|
||||
let x_coord = (cycle - 1) % self.screen[0].len();
|
||||
if sprite_pos.abs_diff(x_coord as i32) <= 1 {
|
||||
self[cycle] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Crt {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
screen: [[false; 40]; 6],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Crt {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for line in self.screen {
|
||||
for char in line {
|
||||
if char {
|
||||
write!(f, "#")?;
|
||||
} else {
|
||||
write!(f, ".")?;
|
||||
}
|
||||
}
|
||||
writeln!(f)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Index<usize> for Crt {
|
||||
type Output = bool;
|
||||
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
let index = index - 1;
|
||||
let x = index % self.screen[0].len();
|
||||
let y = index / self.screen[0].len();
|
||||
&self.screen[y][x]
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::IndexMut<usize> for Crt {
|
||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||
let index = index - 1;
|
||||
let x = index % self.screen[0].len();
|
||||
let y = index / self.screen[0].len();
|
||||
&mut self.screen[y][x]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_index() {
|
||||
let mut input = Crt::default();
|
||||
input[1] = true;
|
||||
input[40] = true;
|
||||
input[41] = true;
|
||||
println!("{}", input);
|
||||
assert_eq!(
|
||||
input,
|
||||
Crt {
|
||||
screen: [
|
||||
[
|
||||
true, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, true
|
||||
],
|
||||
[
|
||||
true, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false
|
||||
],
|
||||
[
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false
|
||||
],
|
||||
[
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false
|
||||
],
|
||||
[
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false
|
||||
],
|
||||
[
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false
|
||||
]
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
139
2022/days/10/src/input.txt
Normal file
139
2022/days/10/src/input.txt
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
noop
|
||||
addx 12
|
||||
addx -5
|
||||
addx -1
|
||||
noop
|
||||
addx 4
|
||||
noop
|
||||
addx 1
|
||||
addx 4
|
||||
noop
|
||||
addx 13
|
||||
addx -8
|
||||
noop
|
||||
addx -19
|
||||
addx 24
|
||||
addx 1
|
||||
noop
|
||||
addx 4
|
||||
noop
|
||||
addx 1
|
||||
addx 5
|
||||
addx -1
|
||||
addx -37
|
||||
addx 16
|
||||
addx -13
|
||||
addx 18
|
||||
addx -11
|
||||
addx 2
|
||||
addx 23
|
||||
noop
|
||||
addx -18
|
||||
addx 9
|
||||
addx -8
|
||||
addx 2
|
||||
addx 5
|
||||
addx 2
|
||||
addx -21
|
||||
addx 26
|
||||
noop
|
||||
addx -15
|
||||
addx 20
|
||||
noop
|
||||
addx 3
|
||||
noop
|
||||
addx -38
|
||||
addx 3
|
||||
noop
|
||||
addx 26
|
||||
addx -4
|
||||
addx -19
|
||||
addx 3
|
||||
addx 1
|
||||
addx 5
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 3
|
||||
noop
|
||||
addx -30
|
||||
addx -4
|
||||
addx 1
|
||||
addx 18
|
||||
addx -8
|
||||
addx -4
|
||||
addx 2
|
||||
noop
|
||||
addx 7
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx -2
|
||||
addx -20
|
||||
addx 27
|
||||
addx -20
|
||||
addx 25
|
||||
addx -2
|
||||
addx -35
|
||||
noop
|
||||
noop
|
||||
addx 4
|
||||
addx 3
|
||||
addx -2
|
||||
addx 5
|
||||
addx 2
|
||||
addx -11
|
||||
addx 1
|
||||
addx 13
|
||||
addx 2
|
||||
addx 5
|
||||
addx 6
|
||||
addx -1
|
||||
addx -2
|
||||
noop
|
||||
addx 7
|
||||
addx -2
|
||||
addx 6
|
||||
addx 1
|
||||
addx -21
|
||||
addx 22
|
||||
addx -38
|
||||
addx 5
|
||||
addx 3
|
||||
addx -1
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx 1
|
||||
addx 4
|
||||
addx 3
|
||||
addx -2
|
||||
addx 2
|
||||
noop
|
||||
addx 7
|
||||
addx -1
|
||||
addx 2
|
||||
addx 4
|
||||
addx -10
|
||||
addx -19
|
||||
addx 35
|
||||
addx -1
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
455
2022/days/10/src/machine.rs
Normal file
455
2022/days/10/src/machine.rs
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
use std::{collections::VecDeque, fmt};
|
||||
|
||||
use crate::crt::Crt;
|
||||
use crate::parse::*;
|
||||
|
||||
pub struct Machine {
|
||||
instructions: VecDeque<Instruction>,
|
||||
current_instruction: Option<(Instruction, usize)>,
|
||||
cycle: usize,
|
||||
x: i32,
|
||||
pub crt: Crt,
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub fn load_program(instructions: VecDeque<Instruction>) -> Self {
|
||||
let mut res = Machine {
|
||||
instructions,
|
||||
current_instruction: None,
|
||||
cycle: 0,
|
||||
x: 1,
|
||||
crt: Crt::default(),
|
||||
};
|
||||
res.fetch_next_instruction();
|
||||
res
|
||||
}
|
||||
|
||||
pub fn step(&mut self) -> (bool, i32) {
|
||||
if self.current_instruction.is_none() {
|
||||
return (false, self.x);
|
||||
}
|
||||
|
||||
//we return x as it was at the beginning of the cycle.
|
||||
let x = self.x;
|
||||
let (instruction, cycles_left) = self.current_instruction.as_mut().unwrap();
|
||||
*cycles_left -= 1;
|
||||
if *cycles_left == 0 {
|
||||
if let Instruction::Addx(i) = instruction {
|
||||
self.x += *i
|
||||
}
|
||||
|
||||
self.fetch_next_instruction();
|
||||
};
|
||||
|
||||
self.cycle += 1;
|
||||
self.crt.draw_pixel(x, self.cycle);
|
||||
(true, x)
|
||||
}
|
||||
|
||||
fn fetch_next_instruction(&mut self) {
|
||||
self.current_instruction = self.instructions.pop_front().map(|i| (i, i.cycles()));
|
||||
}
|
||||
|
||||
//returns the signal strength during the middle of the 20th cycle.
|
||||
pub fn step20(&mut self) -> i32 {
|
||||
for _ in 0..19 {
|
||||
if !self.step().0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
self.step().1 * self.cycle as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Machine {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"cycle={} x={} current instruction: {:?} ({} instructions left)",
|
||||
self.cycle,
|
||||
self.x,
|
||||
self.current_instruction,
|
||||
self.instructions.len()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_screen() {
|
||||
let input = vec![
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::Addx(6),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-8),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(4),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-35),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(24),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(16),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(21),
|
||||
Instruction::Addx(-15),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(8),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-36),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(6),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(7),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-33),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(8),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(17),
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(26),
|
||||
Instruction::Addx(-30),
|
||||
Instruction::Addx(12),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(18),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(9),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-37),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-21),
|
||||
Instruction::Addx(22),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-10),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(20),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
];
|
||||
let mut machine = Machine::load_program(input.into());
|
||||
//step till we cant anymore.
|
||||
while machine.step().0 {}
|
||||
println!("{}", machine.crt);
|
||||
assert_eq!(
|
||||
machine.crt,
|
||||
Crt {
|
||||
screen: [
|
||||
[
|
||||
true, true, false, false, true, true, false, false, true, true, false,
|
||||
false, true, true, false, false, true, true, false, false, true, true,
|
||||
false, false, true, true, false, false, true, true, false, false, true,
|
||||
true, false, false, true, true, false, false
|
||||
],
|
||||
[
|
||||
true, true, true, false, false, false, true, true, true, false, false,
|
||||
false, true, true, true, false, false, false, true, true, true, false,
|
||||
false, false, true, true, true, false, false, false, true, true, true,
|
||||
false, false, false, true, true, true, false
|
||||
],
|
||||
[
|
||||
true, true, true, true, false, false, false, false, true, true, true, true,
|
||||
false, false, false, false, true, true, true, true, false, false, false,
|
||||
false, true, true, true, true, false, false, false, false, true, true,
|
||||
true, true, false, false, false, false
|
||||
],
|
||||
[
|
||||
true, true, true, true, true, false, false, false, false, false, true,
|
||||
true, true, true, true, false, false, false, false, false, true, true,
|
||||
true, true, true, false, false, false, false, false, true, true, true,
|
||||
true, true, false, false, false, false, false
|
||||
],
|
||||
[
|
||||
true, true, true, true, true, true, false, false, false, false, false,
|
||||
false, true, true, true, true, true, true, false, false, false, false,
|
||||
false, false, true, true, true, true, true, true, false, false, false,
|
||||
false, false, false, true, true, true, true
|
||||
],
|
||||
[
|
||||
true, true, true, true, true, true, true, false, false, false, false,
|
||||
false, false, false, true, true, true, true, true, true, true, false,
|
||||
false, false, false, false, false, false, true, true, true, true, true,
|
||||
true, true, false, false, false, false, false
|
||||
]
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_machine() {
|
||||
let input = vec![
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::Addx(6),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-8),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(4),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-35),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(24),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(16),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(21),
|
||||
Instruction::Addx(-15),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(8),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-36),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(6),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(7),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-33),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(8),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(17),
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(26),
|
||||
Instruction::Addx(-30),
|
||||
Instruction::Addx(12),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(18),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(9),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-37),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-21),
|
||||
Instruction::Addx(22),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-10),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(20),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
];
|
||||
let mut machine = Machine::load_program(input.into());
|
||||
|
||||
//20th
|
||||
assert_eq!(machine.step20(), 420);
|
||||
|
||||
machine.step20();
|
||||
//60th
|
||||
assert_eq!(machine.step20(), 1140);
|
||||
|
||||
machine.step20();
|
||||
//100th
|
||||
assert_eq!(machine.step20(), 1800);
|
||||
|
||||
machine.step20();
|
||||
//140th
|
||||
assert_eq!(machine.step20(), 2940);
|
||||
|
||||
machine.step20();
|
||||
//180th
|
||||
assert_eq!(machine.step20(), 2880);
|
||||
|
||||
machine.step20();
|
||||
//220th
|
||||
assert_eq!(machine.step20(), 3960);
|
||||
}
|
||||
}
|
||||
16
2022/days/10/src/main.rs
Normal file
16
2022/days/10/src/main.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
mod machine;
|
||||
mod crt;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(structured_input.clone()));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result:\n{}", part2::part2(structured_input.clone()));
|
||||
}
|
||||
344
2022/days/10/src/parse.rs
Normal file
344
2022/days/10/src/parse.rs
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use nom::{
|
||||
branch::alt,
|
||||
bytes::complete::tag,
|
||||
combinator::{all_consuming, map, value},
|
||||
sequence::preceded,
|
||||
Finish, IResult,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Instruction {
|
||||
NoOp,
|
||||
Addx(i32),
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
fn parse(i: &str) -> IResult<&str, Self> {
|
||||
let noop = tag("noop");
|
||||
let addx = preceded(tag("addx "), nom::character::complete::i32);
|
||||
alt((value(Self::NoOp, noop), map(addx, Self::Addx)))(i)
|
||||
}
|
||||
pub fn cycles(self) -> usize {
|
||||
match self {
|
||||
Self::NoOp => 1,
|
||||
Self::Addx(_) => 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> VecDeque<Instruction> {
|
||||
input
|
||||
.lines()
|
||||
.map(|l| all_consuming(Instruction::parse)(l).finish().unwrap().1)
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!(
|
||||
"addx 15\n",
|
||||
"addx -11\n",
|
||||
"addx 6\n",
|
||||
"addx -3\n",
|
||||
"addx 5\n",
|
||||
"addx -1\n",
|
||||
"addx -8\n",
|
||||
"addx 13\n",
|
||||
"addx 4\n",
|
||||
"noop\n",
|
||||
"addx -1\n",
|
||||
"addx 5\n",
|
||||
"addx -1\n",
|
||||
"addx 5\n",
|
||||
"addx -1\n",
|
||||
"addx 5\n",
|
||||
"addx -1\n",
|
||||
"addx 5\n",
|
||||
"addx -1\n",
|
||||
"addx -35\n",
|
||||
"addx 1\n",
|
||||
"addx 24\n",
|
||||
"addx -19\n",
|
||||
"addx 1\n",
|
||||
"addx 16\n",
|
||||
"addx -11\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 21\n",
|
||||
"addx -15\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx -3\n",
|
||||
"addx 9\n",
|
||||
"addx 1\n",
|
||||
"addx -3\n",
|
||||
"addx 8\n",
|
||||
"addx 1\n",
|
||||
"addx 5\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx -36\n",
|
||||
"noop\n",
|
||||
"addx 1\n",
|
||||
"addx 7\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 2\n",
|
||||
"addx 6\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 7\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"addx -13\n",
|
||||
"addx 13\n",
|
||||
"addx 7\n",
|
||||
"noop\n",
|
||||
"addx 1\n",
|
||||
"addx -33\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 2\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 8\n",
|
||||
"noop\n",
|
||||
"addx -1\n",
|
||||
"addx 2\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"addx 17\n",
|
||||
"addx -9\n",
|
||||
"addx 1\n",
|
||||
"addx 1\n",
|
||||
"addx -3\n",
|
||||
"addx 11\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx -13\n",
|
||||
"addx -19\n",
|
||||
"addx 1\n",
|
||||
"addx 3\n",
|
||||
"addx 26\n",
|
||||
"addx -30\n",
|
||||
"addx 12\n",
|
||||
"addx -1\n",
|
||||
"addx 3\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx -9\n",
|
||||
"addx 18\n",
|
||||
"addx 1\n",
|
||||
"addx 2\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 9\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx -1\n",
|
||||
"addx 2\n",
|
||||
"addx -37\n",
|
||||
"addx 1\n",
|
||||
"addx 3\n",
|
||||
"noop\n",
|
||||
"addx 15\n",
|
||||
"addx -21\n",
|
||||
"addx 22\n",
|
||||
"addx -6\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"addx 2\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"addx -10\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 20\n",
|
||||
"addx 1\n",
|
||||
"addx 2\n",
|
||||
"addx 2\n",
|
||||
"addx -6\n",
|
||||
"addx -11\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::Addx(6),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-8),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(4),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-35),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(24),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(16),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(21),
|
||||
Instruction::Addx(-15),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(8),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-36),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(6),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(7),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-33),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(8),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(17),
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(26),
|
||||
Instruction::Addx(-30),
|
||||
Instruction::Addx(12),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(18),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(9),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-37),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-21),
|
||||
Instruction::Addx(22),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-10),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(20),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
191
2022/days/10/src/part1.rs
Normal file
191
2022/days/10/src/part1.rs
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use crate::{parse::*, machine::Machine};
|
||||
|
||||
pub fn part1(input: VecDeque<Instruction>) -> i32 {
|
||||
let mut machine = Machine::load_program(input.into());
|
||||
let mut total = 0;
|
||||
|
||||
//20th
|
||||
total+=machine.step20();
|
||||
|
||||
machine.step20();
|
||||
//60th
|
||||
total+=machine.step20();
|
||||
|
||||
machine.step20();
|
||||
//100th
|
||||
total+=machine.step20();
|
||||
|
||||
machine.step20();
|
||||
//140th
|
||||
total+=machine.step20();
|
||||
|
||||
machine.step20();
|
||||
//180th
|
||||
total+=machine.step20();
|
||||
|
||||
machine.step20();
|
||||
//220th
|
||||
total+=machine.step20();
|
||||
|
||||
total
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::Addx(6),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-8),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(4),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-35),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(24),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(16),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(21),
|
||||
Instruction::Addx(-15),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(8),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-36),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(6),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(7),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-33),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(8),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(17),
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(26),
|
||||
Instruction::Addx(-30),
|
||||
Instruction::Addx(12),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(18),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(9),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-37),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-21),
|
||||
Instruction::Addx(22),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-10),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(20),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
];
|
||||
assert_eq!(part1(input.into()), 13140)
|
||||
}
|
||||
}
|
||||
19
2022/days/10/src/part2.rs
Normal file
19
2022/days/10/src/part2.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use crate::{crt::Crt, parse::*, machine::Machine};
|
||||
|
||||
pub fn part2(input: VecDeque<Instruction>) -> Crt {
|
||||
let mut machine = Machine::load_program(input);
|
||||
while machine.step().0 {};
|
||||
machine.crt
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
assert_eq!(0, 0);
|
||||
}
|
||||
}
|
||||
9
2022/template/Cargo.toml
Normal file
9
2022/template/Cargo.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "template"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
0
2022/template/src/input.txt
Normal file
0
2022/template/src/input.txt
Normal file
14
2022/template/src/main.rs
Normal file
14
2022/template/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
16
2022/template/src/parse.rs
Normal file
16
2022/template/src/parse.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
pub type StructuredInput = usize;
|
||||
|
||||
pub fn parse(input: &str) -> StructuredInput {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!();
|
||||
assert_eq!(0, 0);
|
||||
}
|
||||
}
|
||||
15
2022/template/src/part1.rs
Normal file
15
2022/template/src/part1.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part1(input: &StructuredInput) -> usize {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
assert_eq!(0, 0);
|
||||
}
|
||||
}
|
||||
15
2022/template/src/part2.rs
Normal file
15
2022/template/src/part2.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part2(input: &StructuredInput) -> usize {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
assert_eq!(0, 0);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue