use std::iter; use std::fs; use std::env; use topological_sort::TopologicalSort; #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] struct Rule ( i32, i32 ); fn main() { println!("Hello, AoC day 05!"); let args: Vec<String> = env::args().collect(); if args.len() != 2 { println!("wrong number of arguments!"); std::process::exit(1); } let file_path = &args[1]; let contents = fs::read_to_string(file_path).expect("Should have been able to read the file"); let (first, second) = contents.split_once("\n\n").unwrap(); let rules: Vec<Rule> = first .lines() .map(|line| { let (before, after) = line.split_once("|").unwrap(); Rule(before.parse().unwrap(), after.parse().unwrap()) }) .collect(); let updates = second.lines(); let mut good_sum: i32 = 0; let mut bad_sum: i32 = 0; for update in updates { let pages: Vec<i32> = update .split(",") .map(|page| page.parse::<i32>().unwrap()) .collect(); let mut my_sort: TopologicalSort::<i32> = TopologicalSort::new(); rules .iter() .filter(|&Rule(a, b)| pages.contains(a) && pages.contains(b)) .for_each(|&Rule(a, b)| my_sort.add_dependency(a, b)); let true_pages: Vec<i32> = iter::from_fn(|| my_sort.pop()) .filter(|p| pages.contains(p)) .collect(); let middle: i32 = true_pages.get((true_pages.len() - 1) / 2) .expect("error finding the halfway point"); if iter::zip(pages.iter(), true_pages.iter()).all(|(a, b)| a==b) { // it's good! good_sum += middle; } else { // it's bad! bad_sum += middle; } } println!("the sum of middle pages of good updates is {good_sum}"); println!("and the bad updates is {bad_sum}"); }