#[derive(Debug)] struct Assignment { left: (u32, u32), right: (u32, u32), } fn main() { let contents = std::fs::read_to_string("data.txt").expect("Failed to read file"); let lines: Vec<&str> = contents.lines().collect(); let assignments: Vec = lines.iter().map(|x| parse_line(&x)).collect(); // Part 1 let num_contained: usize = assignments .iter() .map(|a| any_fully_contained(&a)) .filter(|&x| x) .collect::>() .len(); println!("Number fully contained: {:?}", num_contained); // Part 2 let num_overlap: usize = assignments .iter() .map(|a| any_overlap(&a)) .filter(|&x| x) .collect::>() .len(); println!("Number overlapping: {:?}", num_overlap); } fn parse_line(l: &str) -> Assignment { let parts: Vec<&str> = l.split(',').collect(); let pairs: Vec> = parts.iter().map(|x| x.split('-').collect()).collect(); let pairs: Vec> = pairs // map to u32 .iter() .map(|x| x.iter().map(|y| y.parse().unwrap()).collect()) .collect(); Assignment { left: (pairs[0][0], pairs[0][1]), right: (pairs[1][0], pairs[1][1]), } } fn any_fully_contained(a: &Assignment) -> bool { (a.left.0 <= a.right.0 && a.left.1 >= a.right.1) || // left fully contains right (a.right.0 <= a.left.0 && a.right.1 >= a.left.1) // or right fully contains left } fn any_overlap(a: &Assignment) -> bool { (a.left.0 >= a.right.0 && a.left.0 <= a.right.1) || (a.left.1 >= a.right.0 && a.left.1 <= a.right.1) || (a.right.0 >= a.left.0 && a.right.0 <= a.left.1) || (a.right.1 >= a.left.0 && a.right.1 <= a.left.1) }