From 4980b285e8f993d9f0b8a069a23989877daa3422 Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Mon, 18 Dec 2023 09:36:31 -0500 Subject: [PATCH] update day3 --- old/day01/Cargo.lock | 7 -- old/day01/Cargo.toml | 8 -- old/day01/src/main.rs | 48 ----------- src/day3.rs | 181 ++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 5 files changed, 182 insertions(+), 63 deletions(-) delete mode 100644 old/day01/Cargo.lock delete mode 100644 old/day01/Cargo.toml delete mode 100644 old/day01/src/main.rs create mode 100644 src/day3.rs diff --git a/old/day01/Cargo.lock b/old/day01/Cargo.lock deleted file mode 100644 index ae5bfe8..0000000 --- a/old/day01/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "day1" -version = "0.1.0" diff --git a/old/day01/Cargo.toml b/old/day01/Cargo.toml deleted file mode 100644 index a3c4e52..0000000 --- a/old/day01/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "day1" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/old/day01/src/main.rs b/old/day01/src/main.rs deleted file mode 100644 index 4f626d9..0000000 --- a/old/day01/src/main.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::fs; - -fn main() { - let input = fs::read_to_string("input.txt").unwrap(); - let input = input.split('\n'); - let mut sum = 0; - for line in input { - let str_nums: Vec<(&str, &str)> = vec![("one", "1"), ("two", "2"), ("three", "3"), ("four", "4"), ("five", "5"), ("six", "6"), ("seven", "7"), ("eight", "8"), ("nine", "9")]; - let mut matches: Vec<(usize, &str)> = vec![]; - for str_num in str_nums { - // Get every alphabetic number in the string with it's index - let str_match: Vec<_> = line.match_indices(str_num.0).collect(); - // convert the string to a numeral - let mut str_match: Vec<_> = str_match.iter().map(|x| return (x.0, str_num.1)).collect(); - matches.append(&mut str_match); - } - // get the numerials from the line with their index - let mut num_matches: Vec<(usize, &str)> = line.match_indices(|x: char| x.is_numeric()).collect(); - matches.append(&mut num_matches); - // sort by index - matches.sort_by(|lhs, rhs| lhs.cmp(rhs)); - let num = (matches.first().unwrap().1).to_owned() + (matches.last().unwrap().1); - sum += num.parse::().unwrap(); - } - - println!("{}", sum); -} - - - - - -// use std::fs; - -// fn main() { -// let input = fs::read_to_string("input.txt").unwrap(); -// let input = input.split('\n'); -// let mut sum = 0; -// for line in input { -// let chars: Vec= line.chars().filter(|x| x.is_numeric()).collect(); -// let mut num = chars.first().unwrap().to_string(); -// num += &chars.last().unwrap().to_string(); -// let num: u32 = num.parse().unwrap(); -// sum += num; -// } - -// println!("{}", sum); -// } diff --git a/src/day3.rs b/src/day3.rs new file mode 100644 index 0000000..00c7e15 --- /dev/null +++ b/src/day3.rs @@ -0,0 +1,181 @@ +use std::collections::HashMap; + +use aoc_runner_derive::{aoc, aoc_generator}; +use array2d::Array2D; + +#[aoc_generator(day3)] +fn parse(input: &str) -> Array2D { + let rows: Vec<&str> = input.split("\n").collect(); + let mut array = Vec::new(); + for row in rows { + let row_vec: Vec = row.chars().collect(); + array.push(row_vec); + } + + Array2D::from_rows(&array).unwrap() +} + +#[aoc(day3, part1)] +fn part1(array_2d: &Array2D) -> u32 { + let mut r = 0; + for (y, row_iter) in array_2d.rows_iter().enumerate() { + let mut checked = false; + for (x, element) in row_iter.enumerate() { + let d: char = element.clone(); + if d.is_digit(10) && !checked { + if !get_neighbors(x, y, &array_2d).is_empty() { + checked = true; + + r += get_number(x, y, &array_2d) + } + } else if !d.is_digit(10) { + checked = false; + } + } + } + + r +} + +fn get_number(x: usize, y: usize, array2d: &Array2D) -> u32 { + // We're dealing with only 3 digits numbers + let mut i = x.clone(); + let mut j = x.clone() - 1; + let mut next_neighbors = Vec::new(); + let mut prev_neighbors = Vec::new(); + while array2d.get(y, i).is_some() && array2d.get(y, i).unwrap().is_digit(10) { + next_neighbors.push(array2d.get(y, i).unwrap()); + i += 1 + } + while array2d.get(y, j).is_some() && array2d.get(y, j).unwrap().is_digit(10) { + prev_neighbors.push(array2d.get(y, j).unwrap()); + if j > 0 { + j -= 1 + } else { + break; + } + } + + let mut prev: Vec<&char> = prev_neighbors.clone().into_iter().rev().collect(); + prev.append(&mut next_neighbors); + + prev + .into_iter() + .fold(String::new(), |a, b| a + &b.to_string()) + .parse() + .unwrap() +} + +fn get_neighbors(x: usize, y: usize, array2d: &Array2D) -> Vec<&char> { + let mut neighbors = Vec::new(); + neighbors.push(array2d.get(y, x.checked_add(1).unwrap())); + if x > 0 { + neighbors.push(array2d.get(y, x.checked_sub(1).unwrap())); + neighbors.push(array2d.get(y.checked_add(1).unwrap(), x.checked_sub(1).unwrap())); + } + if y > 0 { + neighbors.push(array2d.get(y.checked_sub(1).unwrap(), x)); + neighbors.push(array2d.get(y.checked_sub(1).unwrap(), x.checked_add(1).unwrap())); + } + if x > 0 && y > 0 { + neighbors.push(array2d.get(y.checked_sub(1).unwrap(), x.checked_sub(1).unwrap())); + } + neighbors.push(array2d.get(y.checked_add(1).unwrap(), x)); + neighbors.push(array2d.get(y.checked_add(1).unwrap(), x.checked_add(1).unwrap())); + + neighbors + .into_iter() + .flatten() + .filter(|c| !c.is_digit(10) && **c != '.') + .collect() +} + + + +#[aoc(day3, part2)] +fn part2(array_2d: &Array2D) -> u32 { + // let mut r = Vec::new(); + let mut stars_count: HashMap<(usize, usize), Vec> = HashMap::new(); + for (y, row_iter) in array_2d.rows_iter().enumerate() { + let mut checked = false; + for (x, element) in row_iter.enumerate() { + let d: char = element.clone(); + if d.is_digit(10) && !checked { + let star_vec = get_neighboring_star(x, y, &array_2d); + if !star_vec.is_empty() { + let (x_star, y_star, _) = star_vec.first().unwrap().clone(); + let key = (x_star, y_star); + let gear = get_number(x, y, &array_2d); + if stars_count.contains_key(&key) { + let mut v: Vec = stars_count.get(&(x_star, y_star)).unwrap().clone(); + v.push(gear); + stars_count.insert(key, v); + } else { + stars_count.insert(key, vec![gear]); + } + checked = true + } + } else if !d.is_digit(10) { + checked = false; + } + } + } + let r = stars_count.iter().fold(0u32, |acc, (_, gears)| { + if gears.len() == 2 { + acc + gears.first().unwrap() * gears.last().unwrap() + } else { + acc + } + }); + + r +} + +fn get_neighboring_star(x: usize, y: usize, array2d: &Array2D) -> Vec<(usize, usize, Option<&char>)> { + let mut neighbors: Vec<(usize, usize, Option<&char>)> = Vec::new(); + neighbors.push((x.checked_add(1).unwrap(), y, array2d.get(y, x.checked_add(1).unwrap()))); + if x > 0 { + neighbors.push((x.checked_sub(1).unwrap(), y, array2d.get(y, x.checked_sub(1).unwrap()))); + neighbors.push((x.checked_sub(1).unwrap(), y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x.checked_sub(1).unwrap()))); + } + if y > 0 { + neighbors.push((x, y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x))); + neighbors.push((x.checked_add(1).unwrap(), y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x.checked_add(1).unwrap()))); + } + if x > 0 && y > 0 { + neighbors.push((x.checked_sub(1).unwrap(), y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x.checked_sub(1).unwrap()))); + } + neighbors.push((x, y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x))); + neighbors.push((x.checked_add(1).unwrap(), y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x.checked_add(1).unwrap()))); + + neighbors + .into_iter() + .filter(|(_, _, c)| c.is_some() && c.unwrap() == &'*') + .collect::)>>() +} + +#[cfg(test)] +mod tests { + use super::*; + + const EX: &str = r"467..114.. +...*...... +..35..633. +......#... +617*...... +.....+.58. +..592..... +......755. +...$.*.... +.664.598.."; + + #[test] + fn part1_example() { + assert_eq!(part1(&parse(EX)), 4361); + } + + #[test] + fn part2_example() { + assert_eq!(part2(&parse(EX)), 467835); + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 99df8a3..c1d0372 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +mod day3; mod day14; mod day13; mod day12;