From b8f85706f1dfaa208ae7ffd2b84695f7e2b2cda5 Mon Sep 17 00:00:00 2001 From: Gabe Venberg Date: Fri, 1 Dec 2023 08:15:09 -0600 Subject: [PATCH] inital commit --- Cargo.lock | 197 ++++++++++++++++++++++++++++++++++++++ Cargo.toml | 21 ++++ aoc_libs/Cargo.toml | 6 ++ aoc_libs/src/lib.rs | 1 + aoc_libs/src/points.rs | 211 +++++++++++++++++++++++++++++++++++++++++ template/Cargo.toml | 9 ++ template/src/input.txt | 0 template/src/main.rs | 14 +++ template/src/parse.rs | 14 +++ template/src/part1.rs | 14 +++ template/src/part2.rs | 15 +++ 11 files changed, 502 insertions(+) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 aoc_libs/Cargo.toml create mode 100644 aoc_libs/src/lib.rs create mode 100644 aoc_libs/src/points.rs create mode 100644 template/Cargo.toml create mode 100644 template/src/input.txt create mode 100644 template/src/main.rs create mode 100644 template/src/parse.rs create mode 100644 template/src/part1.rs create mode 100644 template/src/part2.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..e2cfc24 --- /dev/null +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..47faac1 --- /dev/null +++ b/Cargo.toml @@ -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" diff --git a/aoc_libs/Cargo.toml b/aoc_libs/Cargo.toml new file mode 100644 index 0000000..63d082f --- /dev/null +++ b/aoc_libs/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "aoc_libs" +version.workspace = true +authors.workspace = true +edition.workspace = true +description.workspace = true diff --git a/aoc_libs/src/lib.rs b/aoc_libs/src/lib.rs new file mode 100644 index 0000000..2111939 --- /dev/null +++ b/aoc_libs/src/lib.rs @@ -0,0 +1 @@ +pub mod points; diff --git a/aoc_libs/src/points.rs b/aoc_libs/src/points.rs new file mode 100644 index 0000000..74a92c6 --- /dev/null +++ b/aoc_libs/src/points.rs @@ -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 { + 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 { + matrix: [[T; X]; Y], + max_point: Point, + min_point: Point, + zero_coord: UPoint, +} + +impl 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 std::ops::IndexMut 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 std::ops::Index 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 From> for [[T; X]; Y] { + fn from(value: FourQuadrantMatrix<{ X }, { Y }, T>) -> Self { + value.matrix + } +} diff --git a/template/Cargo.toml b/template/Cargo.toml new file mode 100644 index 0000000..801326a --- /dev/null +++ b/template/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "template" +authors.workspace = true +description.workspace = true +version.workspace = true +edition.workspace = true + +[dependencies] +aoc_libs.workspace = true diff --git a/template/src/input.txt b/template/src/input.txt new file mode 100644 index 0000000..e69de29 diff --git a/template/src/main.rs b/template/src/main.rs new file mode 100644 index 0000000..e282b24 --- /dev/null +++ b/template/src/main.rs @@ -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()); + + println!("Part Two"); + println!("Result: {}", part2::part2()); +} diff --git a/template/src/parse.rs b/template/src/parse.rs new file mode 100644 index 0000000..29de48b --- /dev/null +++ b/template/src/parse.rs @@ -0,0 +1,14 @@ +pub fn parse(input: &str) -> usize { + unimplemented!() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse() { + let input = concat!(); + assert_eq!(0, 0); + } +} diff --git a/template/src/part1.rs b/template/src/part1.rs new file mode 100644 index 0000000..dd46fd2 --- /dev/null +++ b/template/src/part1.rs @@ -0,0 +1,14 @@ +use crate::parse::* +pub fn part1() -> usize { + unimplemented!() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part1() { + assert_eq!(0, 0); + } +} diff --git a/template/src/part2.rs b/template/src/part2.rs new file mode 100644 index 0000000..6d129e2 --- /dev/null +++ b/template/src/part2.rs @@ -0,0 +1,15 @@ +use crate::parse::* + +pub fn part2() -> usize { + unimplemented!() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part2() { + assert_eq!(0, 0); + } +}