From c3849c1ad41100af8ebc1eb80b96dfb76fc6fbee Mon Sep 17 00:00:00 2001 From: Andrew Glaze Date: Mon, 18 Dec 2023 09:37:35 -0500 Subject: [PATCH] update day5 --- old/day02/Cargo.lock | 7 -- old/day02/Cargo.toml | 8 -- old/day02/src/main.rs | 83 ------------------ old/day03/Cargo.lock | 16 ---- old/day03/Cargo.toml | 9 -- old/day03/src/main.rs | 193 ------------------------------------------ old/day04/Cargo.lock | 7 -- old/day04/Cargo.toml | 8 -- old/day04/src/main.rs | 99 ---------------------- old/day05/Cargo.lock | 7 -- old/day05/Cargo.toml | 8 -- old/day05/src/main.rs | 93 -------------------- src/day5.rs | 136 +++++++++++++++++++++++++++++ src/lib.rs | 1 + 14 files changed, 137 insertions(+), 538 deletions(-) delete mode 100644 old/day02/Cargo.lock delete mode 100644 old/day02/Cargo.toml delete mode 100644 old/day02/src/main.rs delete mode 100644 old/day03/Cargo.lock delete mode 100644 old/day03/Cargo.toml delete mode 100644 old/day03/src/main.rs delete mode 100644 old/day04/Cargo.lock delete mode 100644 old/day04/Cargo.toml delete mode 100644 old/day04/src/main.rs delete mode 100644 old/day05/Cargo.lock delete mode 100644 old/day05/Cargo.toml delete mode 100644 old/day05/src/main.rs create mode 100644 src/day5.rs diff --git a/old/day02/Cargo.lock b/old/day02/Cargo.lock deleted file mode 100644 index 63c2f60..0000000 --- a/old/day02/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 = "day2" -version = "0.1.0" diff --git a/old/day02/Cargo.toml b/old/day02/Cargo.toml deleted file mode 100644 index 8aa34bb..0000000 --- a/old/day02/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "day2" -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/day02/src/main.rs b/old/day02/src/main.rs deleted file mode 100644 index 907bd3e..0000000 --- a/old/day02/src/main.rs +++ /dev/null @@ -1,83 +0,0 @@ -use std::{fs, cmp::max}; - -fn main() { - let input = fs::read_to_string("input.txt").unwrap(); - let input: Vec<_> = input.split('\n').collect(); - let mut sum = 0; - for line in input { - let split:Vec<_> = line.split(':').collect(); - let rounds: Vec<_> = split.last().unwrap().split(';').collect(); - let rounds: Vec<_> = rounds.iter() - .map(|x| { - x.split(',').collect::>() - }).collect(); - - let rounds: Vec<_> = rounds.iter() - .map(|x| { - x.iter().map(|x| { - x.trim().split(' ').collect::>() - }).collect::>() - }).collect(); - let (mut r_max, mut g_max, mut b_max) = (0, 0, 0); - for round in rounds { - for set in round { - let color = set.last().unwrap(); - let num: i32 = set.first().unwrap().parse().unwrap(); - match *color { - "red" => r_max = max(num, r_max), - "blue" => b_max = max(num, b_max), - "green" => g_max = max(num, g_max), - &_ => todo!() - } - } - - } - //println!("{}", r_max); - sum += r_max * g_max * b_max; - } - println!("{}", sum); - -} - - - -// use std::fs; - -// fn main() { -// let input = fs::read_to_string("input.txt").unwrap(); -// let input: Vec<_> = input.split('\n').collect(); -// let mut game_id = 0; -// let (r_max, g_max, b_max) = (12, 13, 14); -// let mut sum = 0; -// for line in input { -// game_id += 1; -// let split:Vec<_> = line.split(':').collect(); -// let rounds: Vec<_> = split.last().unwrap().split(';').collect(); -// let rounds: Vec<_> = rounds.iter().map(|x| x.split(',').collect::>()).collect(); -// let rounds: Vec<_> = rounds.iter().map(|x| x.iter().map(|x| x.trim().split(' ').collect::>()).collect::>()).collect(); -// let mut sad = false; - -// for round in rounds { -// let (mut r_cur, mut g_cur, mut b_cur) = (0, 0, 0); -// for set in round { -// let color = set.last().unwrap(); -// let num: i32 = set.first().unwrap().parse().unwrap(); -// match *color { -// "red" => r_cur += num, -// "blue" => b_cur += num, -// "green" => g_cur += num, -// &_ => todo!() -// } -// } - -// if r_cur > r_max || b_cur > b_max || g_cur > g_max { -// sad = true; -// } -// } -// if !sad { -// sum += game_id; -// } -// } -// println!("{}", sum); - -// } diff --git a/old/day03/Cargo.lock b/old/day03/Cargo.lock deleted file mode 100644 index bd1f69f..0000000 --- a/old/day03/Cargo.lock +++ /dev/null @@ -1,16 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "array2d" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79093d31d0a9c7832c71ad74dd945b7861f721e6f242aa67be253a5eecbac937" - -[[package]] -name = "day3" -version = "0.1.0" -dependencies = [ - "array2d", -] diff --git a/old/day03/Cargo.toml b/old/day03/Cargo.toml deleted file mode 100644 index 1ac740b..0000000 --- a/old/day03/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "day3" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -array2d = "0.3.0" diff --git a/old/day03/src/main.rs b/old/day03/src/main.rs deleted file mode 100644 index 8efc4e6..0000000 --- a/old/day03/src/main.rs +++ /dev/null @@ -1,193 +0,0 @@ -use std::collections::HashMap; -use std::fs; - -use array2d::Array2D; - -// pub fn main() { -// let input = fs::read_to_string("input.txt").unwrap(); -// let array_2d = get_map(&input); -// // 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 -// } -// }); - -// println!("{}", r); -// } - -pub fn main() { - let input = fs::read_to_string("input.txt").unwrap(); - let array_2d = get_map(&input); - 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; - } - } - } - - println!("{}", r); -} - -fn get_map(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() -} - -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() -} - -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::)>>() -} - -pub fn part_two(input: &str) -> Option { - let array_2d = get_map(input); - // 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 - } - }); - - Some(r) -} diff --git a/old/day04/Cargo.lock b/old/day04/Cargo.lock deleted file mode 100644 index e92c02c..0000000 --- a/old/day04/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 = "day4" -version = "0.1.0" diff --git a/old/day04/Cargo.toml b/old/day04/Cargo.toml deleted file mode 100644 index eb81094..0000000 --- a/old/day04/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "day4" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] \ No newline at end of file diff --git a/old/day04/src/main.rs b/old/day04/src/main.rs deleted file mode 100644 index 6053943..0000000 --- a/old/day04/src/main.rs +++ /dev/null @@ -1,99 +0,0 @@ -use std::fs; -use std::collections::VecDeque; - -fn main() { - let input = fs::read_to_string("input.txt").unwrap(); - - // an array in this format [[card 1: [winning nums][ our nums]]] - let input: Vec<_> = input.split('\n') // split days - .map(|card| &card[(card.find(':').unwrap() + 1)..]) // remove day numbers - .map(|card| card.trim()) // trim extra whitespace - .map(|card| { - card.split('|') // split winning/own numbers - .map(|numbers| { - numbers.trim() // trim whitespace - .split(' ') // split into individual nums - .filter(|x| !x.is_empty()) // remove empty strings - .map(|x| {return x.parse::().unwrap()}) // convert to i32 - .collect::>() - }) - .collect::>() - }) - .collect(); - - let mut queue = VecDeque::from((0..input.len()).collect::>()); - - let mut total_cards = 0; - while !queue.is_empty() { - let card_num = queue.pop_front().unwrap(); - let card = input.get(card_num).unwrap(); - total_cards += 1; - let mut dup_cards = 0; - let winning_nums = card.first().unwrap(); - let our_nums = card.last().unwrap(); - - //dp would kill here, but im lazy - for num in our_nums { - if winning_nums.contains(num) { - dup_cards += 1; - } - } - for card in (card_num + 1)..=(card_num + dup_cards) { - if card < input.len() { - queue.push_back(card); - } - } - } - - - - println!("{:?}", total_cards); -} - - -// use std::fs; - -// fn main() { -// let input = fs::read_to_string("input.txt").unwrap(); - -// // an array in this format [[card 1: [winning nums][ our nums]]] -// let input: Vec<_> = input.split('\n') // split days -// .map(|card| &card[(card.find(':').unwrap() + 1)..]) // remove day numbers -// .map(|card| card.trim()) // trim extra whitespace -// .map(|card| { -// card.split('|') // split winning/own numbers -// .map(|numbers| { -// numbers.trim() // trim whitespace -// .split(' ') // split into individual nums -// .filter(|x| !x.is_empty()) // remove empty strings -// .map(|x| {return x.parse::().unwrap()}) // convert to i32 -// .collect::>() -// }) -// .collect::>() -// }) -// .collect(); - -// let mut total_pts = 0; -// for card in input { -// let mut card_pts = 0; -// let winning_nums = card.first().unwrap(); -// let our_nums = card.last().unwrap(); - -// for num in our_nums { -// if winning_nums.contains(num) { -// if card_pts == 0 { -// card_pts = 1; -// } else { -// card_pts *= 2; -// } -// } -// } - -// //println!("{}", card_pts); -// total_pts += card_pts; -// } - - - -// println!("{:?}", total_pts); -// } diff --git a/old/day05/Cargo.lock b/old/day05/Cargo.lock deleted file mode 100644 index 7a62bb0..0000000 --- a/old/day05/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 = "day5" -version = "0.1.0" diff --git a/old/day05/Cargo.toml b/old/day05/Cargo.toml deleted file mode 100644 index f9b62bf..0000000 --- a/old/day05/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "day5" -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/day05/src/main.rs b/old/day05/src/main.rs deleted file mode 100644 index 8c0df6e..0000000 --- a/old/day05/src/main.rs +++ /dev/null @@ -1,93 +0,0 @@ -use std::fs; - -fn main() { - let input = fs::read_to_string("input.txt").unwrap(); - let mut mappers: Vec<_> = input.split("\n\n") - .map(|maps| &maps[(maps.find(':').unwrap() + 1)..]) - .map(|maps| maps.trim()) - .map(|maps| { - maps.split('\n') - .map(|range| { - range.split(' ') - .map(|num| num.parse::().unwrap()) - .collect::>() - }) - .collect::>() - }) - .collect(); - - let seeds = mappers.first().unwrap().first().unwrap().clone(); - let mappers: &mut [Vec>] = mappers.get_mut(1..).unwrap(); - - for mapper in mappers.into_iter() { - for range in mapper { - range[2] = range[1] + range[2] - 1; - } - } - - let mut cur_vals: Vec<_> = Vec::new(); - for i in 0..seeds.len() / 2 { - let end = seeds[i * 2] + seeds[(i * 2) + 1]; - let mut range: Vec<_> = (seeds[i * 2]..end).collect(); - cur_vals.append(&mut range); - } - println!("{}", cur_vals.len()); - for mapper in mappers { - for val in cur_vals.iter_mut() { - println!("{}", val); - for range in mapper.into_iter() { - if range[1] <= *val && *val <= range[2] { - let diff = *val - range[1]; - *val = range[0] + diff; - break; - } - } - } - } - - println!("{:?}", cur_vals.into_iter().min().unwrap()) -} - - -// use std::fs; - -// fn main() { -// let input = fs::read_to_string("input.txt").unwrap(); -// let mut mappers: Vec<_> = input.split("\n\n") -// .map(|maps| &maps[(maps.find(':').unwrap() + 1)..]) -// .map(|maps| maps.trim()) -// .map(|maps| { -// maps.split('\n') -// .map(|range| { -// range.split(' ') -// .map(|num| num.parse::().unwrap()) -// .collect::>() -// }) -// .collect::>() -// }) -// .collect(); - -// let seeds = mappers.first().unwrap().first().unwrap().clone(); -// let mappers: &mut [Vec>] = mappers.get_mut(1..).unwrap(); - -// for mapper in mappers.into_iter() { -// for range in mapper { -// range[2] = range[1] + range[2] - 1; -// } -// } - -// let mut cur_vals: Vec<_> = seeds; -// for mapper in mappers { -// for val in cur_vals.iter_mut() { -// for range in mapper.into_iter() { -// if range[1] <= *val && *val <= range[2] { -// let diff = *val - range[1]; -// *val = range[0] + diff; -// break; -// } -// } -// } -// } - -// println!("{:?}", cur_vals.into_iter().min().unwrap()) -// } \ No newline at end of file diff --git a/src/day5.rs b/src/day5.rs new file mode 100644 index 0000000..bd4d0a7 --- /dev/null +++ b/src/day5.rs @@ -0,0 +1,136 @@ +use aoc_runner_derive::{aoc, aoc_generator}; + + +#[aoc_generator(day5)] +fn parse(input: &str) -> Vec>> { + let mappers: Vec>> = input.split("\n\n") + .map(|maps| &maps[(maps.find(':').unwrap() + 1)..]) + .map(|maps| maps.trim()) + .map(|maps| { + maps.split('\n') + .map(|range| { + range.split(' ') + .map(|num| num.parse::().unwrap()) + .collect::>() + }) + .collect::>() + }) + .collect(); + + mappers +} + +#[aoc(day5, part1)] +fn part1(mappers: &Vec>>) -> i64 { + let seeds = mappers.first().unwrap().first().unwrap().clone(); + let mut borrow_work_around: Vec>> = Vec::new(); + mappers.clone_into(&mut borrow_work_around); + let mappers: &mut [Vec>] = &mut borrow_work_around.get_mut(1..).unwrap(); + + for mapper in mappers.into_iter() { + for range in mapper { + range[2] = range[1] + range[2] - 1; + } + } + + let mut cur_vals: Vec<_> = seeds; + for mapper in mappers { + for val in cur_vals.iter_mut() { + for range in mapper.into_iter() { + if range[1] <= *val && *val <= range[2] { + let diff = *val - range[1]; + *val = range[0] + diff; + break; + } + } + } + } + + cur_vals.into_iter().min().unwrap() +} + +#[aoc(day5, part2)] +fn part2(mappers: &Vec>>) -> i64 { + let seeds = mappers.first().unwrap().first().unwrap().clone(); + let mut borrow_work_around: Vec>> = Vec::new(); + mappers.clone_into(&mut borrow_work_around); + let mappers: &mut [Vec>] = &mut borrow_work_around.get_mut(1..).unwrap(); + + for mapper in mappers.into_iter() { + for range in mapper { + range[2] = range[1] + range[2] - 1; + } + } + + let mut cur_vals: Vec<_> = Vec::new(); + for i in 0..seeds.len() / 2 { + let end = seeds[i * 2] + seeds[(i * 2) + 1]; + let mut range: Vec<_> = (seeds[i * 2]..end).collect(); + cur_vals.append(&mut range); + } + println!("{}", cur_vals.len()); + for mapper in mappers { + for val in cur_vals.iter_mut() { + println!("{}", val); + for range in mapper.into_iter() { + if range[1] <= *val && *val <= range[2] { + let diff = *val - range[1]; + *val = range[0] + diff; + break; + } + } + } + } + + cur_vals.into_iter().min().unwrap() +} + + +#[cfg(test)] +mod tests { + use super::*; + + const EX: &str = r"seeds: 79 14 55 13 + +seed-to-soil map: +50 98 2 +52 50 48 + +soil-to-fertilizer map: +0 15 37 +37 52 2 +39 0 15 + +fertilizer-to-water map: +49 53 8 +0 11 42 +42 0 7 +57 7 4 + +water-to-light map: +88 18 7 +18 25 70 + +light-to-temperature map: +45 77 23 +81 45 19 +68 64 13 + +temperature-to-humidity map: +0 69 1 +1 0 69 + +humidity-to-location map: +60 56 37 +56 93 4"; + + #[test] + fn part1_example() { + assert_eq!(part1(&parse(EX)), 35); + } + + #[test] + fn part2_example() { + assert_eq!(part2(&parse(EX)), 46); + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index c1d0372..98455a0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +mod day5; mod day3; mod day14; mod day13;