#![allow(dead_code)] use std::collections::HashMap; use std::collections::HashSet; use std::fs::File; use std::io; use std::io::BufRead; use std::iter::FromIterator; use std::path::Path; use std::time::Instant; fn main() { let now = Instant::now(); part_one(); let part_one_duration = now.elapsed(); part_two(); let part_two_duration = now.elapsed(); println!( "p1: {}ms, p2: {}ms", part_one_duration.as_millis(), (part_two_duration - part_one_duration).as_millis() ); } fn read_lines

(filename: P) -> io::Result>> where P: AsRef, { // note that this discards a final newline let file = File::open(filename)?; Ok(io::BufReader::new(file).lines()) } fn part_one() { if let Ok(lines) = read_lines("./inputs/input") { let mut priorities = 0; for line in lines { let mut knapsack = HashMap::::new(); if let Ok(contents) = line { let pocket_one = &contents[0..contents.len() / 2]; let pocket_two = &contents[contents.len() / 2..]; for item in pocket_one.chars() { knapsack.insert(item, true); } for item in pocket_two.chars() { if knapsack.contains_key(&item) { priorities += (item as u32 - 38) % 58; break; } } } } println!("{}", priorities) } } fn part_two() { if let Ok(lines) = read_lines("./inputs/input") { let mut priorities = 0; let mut group: Vec> = Vec::new(); for line in lines { if let Ok(contents) = line { // build the group let knapsack = HashSet::from_iter(contents.chars()); group.push(knapsack); if group.len() != 3 { continue; } if let (Some(one), Some(two), Some(three)) = (group.get(0), group.get(1), group.get(2)) { let intermediate_one: HashSet<&char> = HashSet::from_iter(two.intersection(three)); let intermediate_two: HashSet<&char> = HashSet::from_iter(one.intersection(three)); let mut result = intermediate_one.intersection(&intermediate_two); if let Some(item) = result.next() { // double pointer! priorities += (**item as u32 - 38) % 58; } } group.clear(); } } println!("{}", priorities) } }