summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/day2.rs6
-rw-r--r--src/bin/day3.rs126
2 files changed, 130 insertions, 2 deletions
diff --git a/src/bin/day2.rs b/src/bin/day2.rs
index 8c5c54d..46abcc9 100644
--- a/src/bin/day2.rs
+++ b/src/bin/day2.rs
@@ -1,6 +1,6 @@
#![feature(test)]
-use std::str::FromStr;
use std::error::Error;
+use std::str::FromStr;
const COLORS: [&str; 3] = ["red", "green", "blue"];
const AMOUNT: [u32; 3] = [12, 13, 14];
@@ -12,7 +12,9 @@ struct HelloWorld {
impl FromStr for HelloWorld {
type Err = std::convert::Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
- Ok(HelloWorld { msg: String::from(s), })
+ Ok(HelloWorld {
+ msg: String::from(s),
+ })
}
}
diff --git a/src/bin/day3.rs b/src/bin/day3.rs
new file mode 100644
index 0000000..ec8d49b
--- /dev/null
+++ b/src/bin/day3.rs
@@ -0,0 +1,126 @@
+#![feature(test)]
+use std::error::Error;
+use std::str::FromStr;
+extern crate test;
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use test::Bencher;
+
+ #[bench]
+ fn other(b: &mut Bencher) {
+ b.iter(|| main());
+ }
+}
+
+#[derive(Debug)]
+struct Number {
+ value: u32,
+ begin: usize,
+ end: usize,
+}
+
+#[derive(Debug)]
+struct SchematicLine {
+ numbers: Vec<Number>,
+ symbols: Vec<(usize, char)>,
+}
+
+impl FromStr for SchematicLine {
+ type Err = std::convert::Infallible;
+ fn from_str(line: &str) -> Result<Self, <Self as FromStr>::Err> {
+ let numbers = (1..4).rev().fold(vec![], |mut acc, window_size| {
+ acc.extend(
+ line.as_bytes()
+ .windows(window_size as usize)
+ .enumerate()
+ .filter(|(i, _)| !acc.iter().any(|n: &Number| n.begin <= *i && *i <= n.end))
+ .filter_map(|(i, w)| {
+ if w[0] as char == '+' {
+ return None;
+ }
+ if let Some(num) = std::str::from_utf8(w).ok()?.parse().ok() {
+ Some(Number {
+ value: num,
+ begin: i,
+ end: i + window_size - 1,
+ })
+ } else {
+ None
+ }
+ })
+ .collect::<Vec<_>>(),
+ );
+ acc
+ });
+ let symbols = line
+ .char_indices()
+ .filter(|(_, c)| !c.is_digit(10) && *c != '.')
+ .collect::<Vec<_>>();
+ Ok(SchematicLine { numbers, symbols })
+ }
+}
+
+impl SchematicLine {
+ pub fn check_against_symbols<'a>(&'a self, mut symbols: impl Iterator<Item=&'a (usize, char)> + 'a + Clone) -> impl Iterator<Item=&Number> + 'a {
+ let s = symbols.collect::<Vec<_>>();
+ self.numbers
+ .iter()
+ .filter(move |n| {
+ s.iter().any(|&&(pos, _)| {
+ (pos as i32 - n.begin as i32).abs() <= 1
+ || (pos as i32 - n.end as i32).abs() <= 1
+ }) || self
+ .symbols
+ .iter()
+ .find(|&&(s, _)| {
+ s as isize == n.begin as isize - 1 || s as isize == n.end as isize + 1
+ })
+ .is_some()
+ })
+ }
+
+ pub fn get_gear_products(&self, mut numbers: impl Iterator<Item=&Number>) -> impl Iterator<Item=&u32> {
+ self.symbols
+ .filter(|(i, symbol)| symbol == '*')
+ .map(|(i, _)| i as u32)
+ }
+}
+
+// 467..114.. ...*...... ..35..633. ......#...
+fn main() -> Result<(), Box<dyn Error>> {
+ let file = std::fs::read_to_string("input/3/in.txt")?;
+ let lines: &[SchematicLine] = &file
+ .lines()
+ .map(|line| line.parse().unwrap())
+ .collect::<Vec<_>>();
+ let numbers = lines
+ .windows(3)
+ .enumerate()
+ .fold(vec![], |mut machine_part_numbers, (i, w)| {
+ if i == 0 {
+ machine_part_numbers
+ .extend(w[0].check_against_symbols(w[1].symbols.iter()));
+ }
+ machine_part_numbers
+ .extend(w[1].check_against_symbols(w[0].symbols.iter().chain(w[2].symbols.iter())));
+ if i == lines.len() - 3 {
+ machine_part_numbers
+ .extend(w[2].check_against_symbols(w[1].symbols.iter()));
+ }
+ machine_part_numbers
+ });
+ let part1: u32 = numbers.iter().map(|n| n.value).sum();
+
+ let part2 = lines
+ .windows(3)
+ .enumerate()
+ .fold(vec![], |mut gear_products, (i, w)| {
+ gear_products.extend();
+ gear_products
+ });
+ dbg!(&part2);
+
+ Ok(())
+}