66 lines
1.9 KiB
Rust
66 lines
1.9 KiB
Rust
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}");
|
|
} |