summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bin/5.rs64
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(())
+}