commit 51459c17c6cb58531e33eafb64215692d81ee4db Author: george Date: Sun Dec 3 22:54:20 2023 +0000 days 1-3 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..664d537 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +target/ +*input +*.log diff --git a/day01/Cargo.lock b/day01/Cargo.lock new file mode 100644 index 0000000..c34d77d --- /dev/null +++ b/day01/Cargo.lock @@ -0,0 +1,54 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "day01" +version = "0.1.0" +dependencies = [ + "regex", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" diff --git a/day01/Cargo.toml b/day01/Cargo.toml new file mode 100644 index 0000000..5ec630b --- /dev/null +++ b/day01/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day01" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +regex = "1.10.2" diff --git a/day01/src/main.rs b/day01/src/main.rs new file mode 100644 index 0000000..289e1bc --- /dev/null +++ b/day01/src/main.rs @@ -0,0 +1,45 @@ +use std::io::{stdin, BufRead}; + +const NUM_TEST: [(&str, &str); 9] = [ + ("one", "1"), + ("two", "2"), + ("three", "3"), + ("four", "4"), + ("five", "5"), + ("six", "6"), + ("seven", "7"), + ("eight", "8"), + ("nine", "9"), +]; + +fn main() { + let input = stdin().lock().lines().map(|l| l.unwrap()); + let mut part_one_total = 0; + let mut part_two_total = 0; + + for line in input { + part_one_total += part_one_calc(&line); + part_two_total += part_two_calc(&line); + } + + println!("P1: {} P2: {}", part_one_total, part_two_total); +} + +fn part_two_calc(line: &str) -> usize { + let mut line = String::from(line); + + for str in NUM_TEST { + if line.contains(str.0) { + let swap = str.0.to_string() + str.1 + str.0; + line = line.replace(str.0, &swap); + } + } + part_one_calc(&line) +} + +fn part_one_calc(line: &str) -> usize { + let mut nums = line.chars().filter(|c| c.is_numeric()); + let first = nums.next().unwrap_or('0'); + let last = nums.last().unwrap_or(first); + format!("{}{}", first, last).parse().unwrap() +} diff --git a/day02/Cargo.lock b/day02/Cargo.lock new file mode 100644 index 0000000..91d6451 --- /dev/null +++ b/day02/Cargo.lock @@ -0,0 +1,54 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "day02" +version = "0.1.0" +dependencies = [ + "regex", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" diff --git a/day02/Cargo.toml b/day02/Cargo.toml new file mode 100644 index 0000000..c6376df --- /dev/null +++ b/day02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "day02" +version = "0.1.0" +edition = "2021" + +[dependencies] +regex = "1.10.2" diff --git a/day02/src/main.rs b/day02/src/main.rs new file mode 100644 index 0000000..5150f94 --- /dev/null +++ b/day02/src/main.rs @@ -0,0 +1,61 @@ +use regex::Regex; +use std::io::{stdin, BufRead}; + +type Rgb = (usize, usize, usize); +const THRESHOLD: Rgb = (12, 13, 14); + +fn main() { + let re = Regex::new(r"\d+ (b|r|g)").unwrap(); + let input = stdin().lock().lines().map(|l| l.unwrap()); + let mut id_sum = 0; + let mut water_sum = 0; + + for (i, line) in input.enumerate() { + let mut possible = true; + + let mut max_rgb = (0, 0, 0); + for line_sect in line.split(';') { + let mut rgb = (0, 0, 0); + + let games = re + .find_iter(line_sect) + .map(|l| { + let temp = l.as_str().split_once(' ').unwrap(); + (temp.0.parse::().unwrap(), temp.1) + }) + .collect::>(); + + for game in games.iter() { + match game.1 { + "r" => rgb.0 = game.0, + "g" => rgb.1 = game.0, + "b" => rgb.2 = game.0, + _ => (), + } + if rgb.0 > max_rgb.0 { + max_rgb.0 = rgb.0; + } + + if rgb.1 > max_rgb.1 { + max_rgb.1 = rgb.1; + } + + if rgb.2 > max_rgb.2 { + max_rgb.2 = rgb.2; + } + + if possible && rgb.0 > THRESHOLD.0 || rgb.1 > THRESHOLD.1 || rgb.2 > THRESHOLD.2 { + possible = false; + } + } + } + + let pow = max_rgb.0 * max_rgb.1 * max_rgb.2; + water_sum += pow; + + if possible { + id_sum += i + 1; + } + } + println!("P1: {}, P2: {}", id_sum, water_sum); +} diff --git a/day03/Cargo.lock b/day03/Cargo.lock new file mode 100644 index 0000000..21c74cb --- /dev/null +++ b/day03/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day03" +version = "0.1.0" diff --git a/day03/Cargo.toml b/day03/Cargo.toml new file mode 100644 index 0000000..2804bab --- /dev/null +++ b/day03/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day03" +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/day03/src/main.rs b/day03/src/main.rs new file mode 100644 index 0000000..101c1c1 --- /dev/null +++ b/day03/src/main.rs @@ -0,0 +1,114 @@ +use std::collections::HashMap; +use std::io::{stdin, BufRead}; + +type Point = (usize, usize); +const EMPTY_SYMBOL: char = '.'; +const GEAR_SYMBOL: char = '*'; +const DEFAULT_POINT: Point = (usize::MAX, usize::MAX); + +fn main() { + let input = stdin() + .lock() + .lines() + .map(|l| l.unwrap().chars().collect::>()) + .collect::>(); + + let mut sum = 0; + let mut gear_surrounding_nums: HashMap> = HashMap::new(); + + for (y, row) in input.iter().enumerate() { + let mut current_num = String::new(); + let mut valid = false; + let mut gear_pos = DEFAULT_POINT; + + for (x, col) in row.iter().enumerate() { + if col.is_ascii_digit() { + current_num.push(*col); + let points = points_around(x, y); + + for point in points { + if let Some(adjacent_symbol) = get_at_point(point.0, point.1, &input) { + if !adjacent_symbol.is_ascii_digit() && adjacent_symbol != &EMPTY_SYMBOL { + valid = true; + } + if adjacent_symbol == &GEAR_SYMBOL { + gear_pos = point; + } + } + } + } else if !current_num.is_empty() { + check_and_update_point( + valid, + ¤t_num, + &mut sum, + &gear_pos, + &mut gear_surrounding_nums, + ); + gear_pos = DEFAULT_POINT; + valid = false; + current_num.clear(); + } + } + check_and_update_point( + valid, + ¤t_num, + &mut sum, + &gear_pos, + &mut gear_surrounding_nums, + ); + } + + let part2 = gear_surrounding_nums + .iter() + .filter_map(|gear| match gear.1.len() == 2 { + true => Some(gear.1), + _ => None, + }) + .fold(0, |total, gear_vals| { + total + gear_vals.iter().product::() + }); + + println!("P1: {} P2: {}", sum, part2); +} + +fn check_and_update_point( + valid: bool, + current_num: &str, + sum: &mut usize, + gear_pos: &Point, + gear_surrounding_nums: &mut HashMap>, +) { + if valid { + let numeric_val = current_num.parse::().unwrap(); + + *sum += numeric_val; + if *gear_pos != DEFAULT_POINT { + let gears = gear_surrounding_nums.get_mut(gear_pos); + if let Some(gear_vec) = gears { + gear_vec.push(numeric_val); + } else { + gear_surrounding_nums.insert(*gear_pos, vec![numeric_val]); + } + } + } +} + +fn get_at_point(x: usize, y: usize, grid: &[Vec]) -> Option<&char> { + if let Some(row) = grid.get(y) { + return row.get(x); + } + None +} + +fn points_around(x: usize, y: usize) -> Vec { + let mut points = Vec::new(); + for i in x.saturating_sub(1)..(x + 2) { + for j in y.saturating_sub(1)..(y + 2) { + if (i, j) == (x, y) { + continue; + } + points.push((i, j)); + } + } + points +}