diff options
-rw-r--r-- | src/bin/5.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/bin/5.rs b/src/bin/5.rs new file mode 100644 index 0000000..7295392 --- /dev/null +++ b/src/bin/5.rs @@ -0,0 +1,64 @@ +//! Awful... + +use std::{cmp::Ordering, collections::{HashMap, HashSet}, error::Error, fs::File, io::{BufRead, BufReader}}; + +fn main() -> Result<(), Box<dyn Error>> { + let f = File::open("input/5.test")?; + let mut f = BufReader::new(f); + + let mut must_precede: HashMap<i64, HashSet<i64>> = HashMap::new(); + let mut line = String::new(); + + loop { + line.clear(); + f.read_line(&mut line)?; + let line = line.trim_end(); + if line.is_empty() { break }; + let (lhs, rhs) = line.split_once('|').ok_or("Invalid dependency line")?; + must_precede.entry(lhs.parse()?).or_default().insert(rhs.parse()?); + } + + let mut pages: Vec<i64> = Vec::new(); + let mut p1_total = 0; + let mut p2_total = 0; + + loop { + line.clear(); + if f.read_line(&mut line)? == 0 { + break; + }; + pages.clear(); + // Ugh... + pages.extend(line.trim_end().split(',').map(|p| p.parse::<i64>().unwrap())); + let mut valid = true; + 'outer: for (i, page) in pages.iter().enumerate().skip(1) { + let Some(succ) = must_precede.get(page) else { + continue; + }; + for p in &pages[0..i] { + if succ.contains(p) { + valid = false; + break 'outer; + } + } + } + if valid { + p1_total += pages[pages.len() / 2]; + } else { + pages.sort_by(|a, b| { + if let Some(succ) = must_precede.get(a) { + if succ.contains(b) { + Ordering::Less + } else { + Ordering::Greater + } + } else { + Ordering::Equal + } + }); + p2_total += pages[pages.len() / 2]; + } + } + println!("{p1_total}\n{p2_total}"); + Ok(()) +} |