#![feature(iterator_try_collect, iter_collect_into)] use std::collections::HashSet; use std::fs; use std::io::{self, BufRead}; fn main() { let filename = "etc/p03.txt"; let file = fs::File::open(filename).expect("Can't open file"); let reader = io::BufReader::new(file); println!("PART ONE ---------------"); let lines: Vec = reader .lines() .try_collect() .expect("Expected all lines to be valid"); part1(&lines); println!("\n PART TWO ---------------"); part2(&lines); } fn to_priority(c: char) -> Result { if c.is_ascii_uppercase() { Ok(c as u32 - 'A' as u32 + 26 + 1) } else if c.is_ascii_lowercase() { Ok(c as u32 - 'a' as u32 + 1) } else { Err("Can't convert non-alphanumeric") } } fn part1(lines: &[String]) { let mut sum: u32 = 0; let mut left_set = HashSet::::new(); for line in lines { let (left, right) = line.split_at(line.len() / 2); left.chars().collect_into(&mut left_set); let outlier = right .chars() .find(|c| left_set.contains(c)) .expect("Expected at least one duplicate item"); let priority = to_priority(outlier).unwrap(); dbg!(outlier, priority); sum += priority; left_set.clear(); } println!("Sum: {}", sum); } fn part2(lines: &[String]) { const GROUP_SIZE: usize = 3; let mut sets = Vec::with_capacity(GROUP_SIZE - 1); for _ in 0..GROUP_SIZE - 1 { sets.push(HashSet::::new()) } let mut sum: u32 = 0; for chunk in lines.chunks(GROUP_SIZE) { for i in 0..GROUP_SIZE - 1 { sets[i].clear(); chunk[i].chars().collect_into(&mut sets[i]); } let outlier = chunk[GROUP_SIZE - 1] .chars() .find(|c| sets[0..GROUP_SIZE - 1].iter().all(|s| s.contains(c))) .expect("Expect at least one outlier"); let priority = to_priority(outlier).unwrap(); dbg!(outlier, priority); sum += priority; } println!("Sum: {}", sum); }