From b9ad953c766250ac10cf9b726368f5b47236fe7a Mon Sep 17 00:00:00 2001 From: Lucas Resch Date: Sun, 3 Dec 2023 11:27:22 +0100 Subject: [PATCH] 2023-03: Solve first puzzle --- 2023-rust/README.md | 7 +- 2023-rust/data/examples/03.txt | 10 +++ 2023-rust/src/bin/03.rs | 138 +++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 2023-rust/data/examples/03.txt create mode 100644 2023-rust/src/bin/03.rs diff --git a/2023-rust/README.md b/2023-rust/README.md index b4f23b9..7e28c94 100644 --- a/2023-rust/README.md +++ b/2023-rust/README.md @@ -9,10 +9,11 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www. | Day | Part 1 | Part 2 | | :---: | :---: | :---: | -| [Day 1](./src/bin/01.rs) | `66.9µs` | `657.5µs` | -| [Day 2](./src/bin/02.rs) | `42.2µs` | `48.9µs` | +| [Day 1](./src/bin/01.rs) | `63.8µs` | `626.0µs` | +| [Day 2](./src/bin/02.rs) | `40.1µs` | `46.9µs` | +| [Day 3](./src/bin/03.rs) | `424.5µs` | `-` | -**Total: 0.82ms** +**Total: 1.20ms** ## Usage diff --git a/2023-rust/data/examples/03.txt b/2023-rust/data/examples/03.txt new file mode 100644 index 0000000..b20187f --- /dev/null +++ b/2023-rust/data/examples/03.txt @@ -0,0 +1,10 @@ +467..114.. +...*...... +..35..633. +......#... +617*...... +.....+.58. +..592..... +......755. +...$.*.... +.664.598.. diff --git a/2023-rust/src/bin/03.rs b/2023-rust/src/bin/03.rs new file mode 100644 index 0000000..4d0b51b --- /dev/null +++ b/2023-rust/src/bin/03.rs @@ -0,0 +1,138 @@ +use std::collections::HashMap; + +use regex::Regex; + +advent_of_code::solution!(3); + +#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] +struct Coordinate { + x: usize, + y: usize, +} + +#[derive(Debug)] +struct EnginePart { + number: u32, + start: Coordinate, + end: Coordinate, +} + +impl EnginePart { + fn neighbors(&self) -> Vec { + let mut neighbors: Vec = Vec::new(); + + let y = self.start.y; + for x in self.start.x..self.end.x + 1 { + // left + if x > 0 && x == self.start.x { + neighbors.push(Coordinate { x: x - 1, y }); + neighbors.push(Coordinate { x: x - 1, y: y + 1 }); + if y > 0 { + neighbors.push(Coordinate { x: x - 1, y: y - 1 }); + } + } + // right + if x == self.end.x { + neighbors.push(Coordinate { x: x + 1, y }); + neighbors.push(Coordinate { x: x + 1, y: y + 1 }); + if y > 0 { + neighbors.push(Coordinate { x: x + 1, y: y - 1 }); + } + } + //top + if y > 0 { + neighbors.push(Coordinate { x, y: y - 1 }); + } + //bottom + neighbors.push(Coordinate { x, y: y + 1 }); + } + + neighbors + } + + pub fn is_valid(&self, symbols: &HashMap) -> bool { + for neighbor in self.neighbors() { + if symbols.contains_key(&neighbor) { + return true; + } + } + false + } +} + +#[derive(Debug)] +struct Symbol { + character: char, +} + +pub fn part_one(input: &str) -> Option { + let parts = parse_engine_parts(input); + let symbols: HashMap = parse_symbols(input); + + parts + .iter() + .filter(|part| part.is_valid(&symbols)) + .map(|part| part.number) + .reduce(|acc, number| acc + number) +} + +pub fn part_two(_input: &str) -> Option { + None +} + +fn parse_engine_parts(input: &str) -> Vec { + let mut parts: Vec = Vec::new(); + let regex = Regex::new(r"\d+").unwrap(); + for (y, line) in input.lines().enumerate() { + for number_match in regex.find_iter(line) { + parts.push(EnginePart { + number: number_match.as_str().parse().unwrap(), + start: Coordinate { + x: number_match.start(), + y, + }, + end: Coordinate { + x: number_match.end() - 1, + y, + }, + }) + } + } + parts +} + +fn parse_symbols(input: &str) -> HashMap { + let mut symbols: HashMap = HashMap::new(); + let regex = Regex::new(r"(\+|-|\*|/|=|\$|@|%|#|&)").unwrap(); + for (y, line) in input.lines().enumerate() { + for symbol_match in regex.find_iter(line) { + symbols.insert( + Coordinate { + x: symbol_match.start(), + y, + }, + Symbol { + character: symbol_match.as_str().chars().next().unwrap(), + }, + ); + } + } + symbols +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let result = part_one(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(4361)); + } + + #[test] + fn test_part_two() { + let result = part_two(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, None); + } +}