summaryrefslogtreecommitdiffstats
path: root/src/2020/2/mod.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-12-02 00:33:09 -0500
committerJesse Luehrs <doy@tozt.net>2020-12-02 00:33:09 -0500
commita2abe26e3190ee2105bf1d46066ae48d3c2ad4f0 (patch)
tree7bc9fbff5225d240456733c4377791791961ca38 /src/2020/2/mod.rs
parentb87a72594515f4a05aee7622db96269f2ee9c0af (diff)
downloadadvent-of-code-a2abe26e3190ee2105bf1d46066ae48d3c2ad4f0.tar.gz
advent-of-code-a2abe26e3190ee2105bf1d46066ae48d3c2ad4f0.zip
puzzle 2-1
Diffstat (limited to 'src/2020/2/mod.rs')
-rw-r--r--src/2020/2/mod.rs64
1 files changed, 64 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!()
+}