summaryrefslogtreecommitdiffstats
path: root/src/2020
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-12-03 02:39:18 -0500
committerJesse Luehrs <doy@tozt.net>2020-12-03 02:39:18 -0500
commit7a2dc8423a5981dfffae740dd1d1e8d55d75cccc (patch)
tree00b0c0c0a32ad515b5a8364ee6e6bad53880a8d5 /src/2020
parent11db8a9b68cf047320b5d18081cbb692d8b95900 (diff)
downloadadvent-of-code-7a2dc8423a5981dfffae740dd1d1e8d55d75cccc.tar.gz
advent-of-code-7a2dc8423a5981dfffae740dd1d1e8d55d75cccc.zip
day 3
Diffstat (limited to 'src/2020')
-rw-r--r--src/2020/3/mod.rs94
-rw-r--r--src/2020/mod.rs4
2 files changed, 98 insertions, 0 deletions
diff --git a/src/2020/3/mod.rs b/src/2020/3/mod.rs
new file mode 100644
index 0000000..58aabfd
--- /dev/null
+++ b/src/2020/3/mod.rs
@@ -0,0 +1,94 @@
+use anyhow::Context as _;
+use std::io::Read as _;
+
+struct Map {
+ grid: Vec<Vec<bool>>,
+}
+
+impl Map {
+ fn parse(s: &[u8]) -> anyhow::Result<Self> {
+ let mut grid = vec![];
+ let mut current_row = vec![];
+ for c in s {
+ match c {
+ b'#' => {
+ current_row.push(true);
+ }
+ b'.' => {
+ current_row.push(false);
+ }
+ b'\n' => {
+ grid.push(current_row);
+ current_row = vec![];
+ }
+ _ => {
+ return Err(anyhow::anyhow!("invalid map char: '{}'", c));
+ }
+ }
+ }
+ if !current_row.is_empty() {
+ grid.push(current_row);
+ }
+ Ok(Self { grid })
+ }
+
+ fn rows(&self) -> usize {
+ self.grid.len()
+ }
+
+ fn tree_at(&self, x: usize, y: usize) -> anyhow::Result<bool> {
+ // unwrap safe because cycle().nth() can never fail
+ Ok(*self
+ .grid
+ .get(y)
+ .context("row too large")?
+ .iter()
+ .cycle()
+ .nth(x)
+ .unwrap())
+ }
+
+ fn trees_for_slope(
+ &self,
+ x_incr: usize,
+ y_incr: usize,
+ ) -> anyhow::Result<usize> {
+ let mut trees = 0;
+ for r in 0..self.rows() / y_incr {
+ let x = r * x_incr;
+ let y = r * y_incr;
+ if self.tree_at(x, y)? {
+ trees += 1;
+ }
+ }
+ Ok(trees)
+ }
+}
+
+pub fn part1() -> anyhow::Result<()> {
+ let map = read_map()?;
+ println!("{}", map.trees_for_slope(3, 1)?);
+ Ok(())
+}
+
+pub fn part2() -> anyhow::Result<()> {
+ let map = read_map()?;
+ println!(
+ "{}",
+ map.trees_for_slope(1, 1)?
+ * map.trees_for_slope(3, 1)?
+ * map.trees_for_slope(5, 1)?
+ * map.trees_for_slope(7, 1)?
+ * map.trees_for_slope(1, 2)?
+ );
+ Ok(())
+}
+
+fn read_map() -> anyhow::Result<Map> {
+ let mut f = std::fs::File::open("data/3.txt")
+ .context("couldn't find data file 3.txt")?;
+ let mut map_str = vec![];
+ f.read_to_end(&mut map_str)
+ .context("failed to read map contents")?;
+ Map::parse(&map_str)
+}
diff --git a/src/2020/mod.rs b/src/2020/mod.rs
index 87ceb55..ff08a7e 100644
--- a/src/2020/mod.rs
+++ b/src/2020/mod.rs
@@ -2,6 +2,8 @@
mod day1;
#[path = "2/mod.rs"]
mod day2;
+#[path = "3/mod.rs"]
+mod day3;
pub fn run(day: u8, puzzle: u8) -> anyhow::Result<()> {
match (day, puzzle) {
@@ -9,6 +11,8 @@ pub fn run(day: u8, puzzle: u8) -> anyhow::Result<()> {
(1, 2) => day1::part2(),
(2, 1) => day2::part1(),
(2, 2) => day2::part2(),
+ (3, 1) => day3::part1(),
+ (3, 2) => day3::part2(),
_ => Err(anyhow::anyhow!("unknown puzzle {}-{}", day, puzzle)),
}
}