summaryrefslogtreecommitdiffstats
path: root/src/2020
diff options
context:
space:
mode:
Diffstat (limited to 'src/2020')
-rw-r--r--src/2020/2/mod.rs64
-rw-r--r--src/2020/mod.rs4
2 files changed, 68 insertions, 0 deletions
diff --git a/src/2020/2/mod.rs b/src/2020/2/mod.rs
new file mode 100644
index 0000000..88d3f5b
--- /dev/null
+++ b/src/2020/2/mod.rs
@@ -0,0 +1,64 @@
+use anyhow::Context as _;
+use std::io::BufRead as _;
+
+struct Line {
+ c: char,
+ min_times: usize,
+ max_times: usize,
+ password: String,
+}
+
+impl Line {
+ fn parse(line: &str) -> anyhow::Result<Self> {
+ let rx = regex::Regex::new(r"^([0-9]+)-([0-9]+) (.): (.*)$").unwrap();
+ let captures =
+ rx.captures(line).context("line failed to match regex")?;
+ let c = captures
+ .get(3)
+ .unwrap()
+ .as_str()
+ .parse()
+ .context("invalid policy char")?;
+ let min_times = captures
+ .get(1)
+ .unwrap()
+ .as_str()
+ .parse()
+ .context("invalid policy lower bound")?;
+ let max_times = captures
+ .get(2)
+ .unwrap()
+ .as_str()
+ .parse()
+ .context("invalid policy upper bound")?;
+ let password = captures.get(4).unwrap().as_str().to_string();
+ Ok(Self {
+ c,
+ min_times,
+ max_times,
+ password,
+ })
+ }
+
+ fn valid(&self) -> bool {
+ let count = self.password.chars().filter(|c| *c == self.c).count();
+ count >= self.min_times && count <= self.max_times
+ }
+}
+
+pub fn part1() -> anyhow::Result<()> {
+ let f = std::fs::File::open("data/2.txt")
+ .context("couldn't find data file 2.txt")?;
+ let f = std::io::BufReader::new(f);
+ let lines = f
+ .lines()
+ .map(|l| Line::parse(&l.context("failed to read a line")?))
+ .collect::<anyhow::Result<Vec<Line>>>()?;
+ let count = lines.iter().filter(|l| l.valid()).count();
+ println!("{}", count);
+ Ok(())
+}
+
+pub fn part2() -> anyhow::Result<()> {
+ todo!()
+}
diff --git a/src/2020/mod.rs b/src/2020/mod.rs
index 3800c30..87ceb55 100644
--- a/src/2020/mod.rs
+++ b/src/2020/mod.rs
@@ -1,10 +1,14 @@
#[path = "1/mod.rs"]
mod day1;
+#[path = "2/mod.rs"]
+mod day2;
pub fn run(day: u8, puzzle: u8) -> anyhow::Result<()> {
match (day, puzzle) {
(1, 1) => day1::part1(),
(1, 2) => day1::part2(),
+ (2, 1) => day2::part1(),
+ (2, 2) => day2::part2(),
_ => Err(anyhow::anyhow!("unknown puzzle {}-{}", day, puzzle)),
}
}