diff --git a/src/day03.rs b/src/day03.rs index 6c82367..28b0cce 100644 --- a/src/day03.rs +++ b/src/day03.rs @@ -1,5 +1,7 @@ +use std::collections::HashSet; use crate::utils; + pub fn execute_task01(content: &str) { let sum = solve_task01(content); @@ -14,89 +16,40 @@ pub fn execute_task02(content: &str) { fn solve_task01(content: &str) -> i32 { let vector = utils::convert_to_string_slice(&content); - let rucksack_compartments: Vec<(Vec, Vec)> = vector.iter().map(|line| split_rucksack_in_two_compartments(line)).collect(); - let duplicates: Vec = rucksack_compartments.iter() - .flat_map(|(vec1, vec2)| vec1.iter() - .copied() - .flat_map(|entry| vec2.iter().copied().map(move |b| (entry, b))) - .filter(|(a, b)| a == b) - .map(|(a, _)| a)) - .collect(); - - duplicates.iter().copied().map(|c| convert_char_to_prio(&c)).sum() + vector.into_iter() + .map(|x| [&x[..x.len()/2], &x[x.len()/2..]] + .into_iter() + .map(|x| x.chars().collect::>()) + .reduce(|acc, x| &acc & &x).unwrap()) + .map(|x| *x.iter().next().unwrap()) + .map(|c| convert_char_to_prio(c) as i32) + .sum() } fn solve_task02(content: &str) -> i32 { let vector = utils::convert_to_string_slice(&content); - let compartments: Vec> = vector.iter().map(|line| split_rucksack_in_items(line)).collect(); - let mut duplicates: Vec = vec![]; - for i in 0..(compartments.len()/3) { - let first_index = i * 3 + 0; - let second_index = i * 3 + 1; - let third_index = i * 3 + 2; - - let first_vec = compartments.get(first_index).expect("ERR"); - let second_vec = compartments.get(second_index).expect("ERR"); - let third_vec = compartments.get(third_index).expect("ERR"); - - let mut dups: Vec = first_vec.into_iter() - .copied() - .flat_map(|val1| second_vec.into_iter() - .copied() - .flat_map(move |val2| third_vec.into_iter().copied().map(move |val3| (val1, val2, val3)))) - .filter(|(a, b, c)| a == b && b == c) - .map(|(a, _, _)| a) - .collect(); - - duplicates.append(&mut dups) - } - - duplicates.iter().copied().map(|c| convert_char_to_prio(&c)).sum() + vector.chunks(3).into_iter() + .map(|content| [content[0], content[1], content[2]].into_iter() + .map(|x| x.chars().collect::>()) + .reduce(|acc, x| &acc & &x).unwrap()) + .map(|x| *x.iter().next().unwrap()) + .map(|c| convert_char_to_prio(c) as i32) + .sum() } -fn split_rucksack_in_two_compartments(rucksack_content: &str) -> (Vec, Vec) { - let first_compartment: &str = &rucksack_content[..rucksack_content.len()/2]; - let second_compartment: &str = &rucksack_content[rucksack_content.len()/2..]; - - let mut first_compartment_vec: Vec = first_compartment.chars().map(|c| c).collect(); - let mut second_compartment_vec: Vec = second_compartment.chars().map(|c| c).collect(); - - first_compartment_vec.sort(); - first_compartment_vec.dedup(); - second_compartment_vec.sort(); - second_compartment_vec.dedup(); - - return ( first_compartment_vec, second_compartment_vec); -} - -fn split_rucksack_in_items(rucksack_content: &str) -> Vec { - let mut vec: Vec = rucksack_content.chars().map(|c| c).collect(); - - vec.sort(); - vec.dedup(); - - return vec; -} - -pub fn convert_char_to_prio(c: &char) -> i32 { - let c_code = c.clone() as u8; - - if 65 <= c_code && c_code < 91 { - return (c_code - 64 + 26) as i32; +pub fn convert_char_to_prio(c: char) -> u8 { + let c = c as u8; + match c { + b'a'..=b'z' => c - b'a' + 1, + b'A'..=b'Z' => c - b'A' + 27, + _ => unreachable!(), } - - if 97 <= c_code && c_code < 123 { - return (c_code - 96) as i32; - } - - panic!("never should called"); } #[cfg(test)] mod test { - const EXAMPLE01: &'static str = include_str!("input/day03/example01");