diff --git a/src/days/day14.rs b/src/days/day14.rs index 6a1807e..863ac6f 100644 --- a/src/days/day14.rs +++ b/src/days/day14.rs @@ -1,5 +1,5 @@ -use std::{cmp::{self, max}, path::Path, str::FromStr}; +use std::{cmp, path::Path, str::FromStr}; use crate::input::read_into_vec; diff --git a/src/days/day5.rs b/src/days/day5.rs index 6f668f7..0a6b07d 100644 --- a/src/days/day5.rs +++ b/src/days/day5.rs @@ -28,11 +28,17 @@ impl Day5Part1 { } } -struct Day5Part2 {} +struct Day5Part2 { + ordering: Vec, + queues: Vec> +} impl Day5Part2 { fn new() -> Self { - Self{} + Self { + ordering: vec![], + queues: vec![vec![]] + } } } @@ -80,12 +86,69 @@ fn solve_part1(part1: &mut Day5Part1) -> Result { } fn read_input_part2(part2: &mut Day5Part2, path: &Path) -> Result<(), AdventError> { + let mut lines = get_lines(path); + let order_regex = Regex::new(r"(\d+)\|(\d+)").unwrap(); + part2.ordering = lines.by_ref().take_while(|s| { + s.as_ref().unwrap().trim() != "" + }).map(|s| -> Order { + let s = s.as_ref().unwrap().as_str(); + let (_, [l, r]) = order_regex.captures(s).unwrap().extract(); + Order { + left: l.parse::().unwrap(), + right: r.parse::().unwrap() + } + }).collect::>(); + part2.queues = lines.map(|s| { + let s = s.as_ref().unwrap(); + let print_item_regex = Regex::new(r"\d+").unwrap(); + print_item_regex.find_iter(s.as_str()).map(|m| { + m.as_str().parse::().unwrap() + }).collect::>() + }).collect::>>(); Ok(()) } +fn is_correct2(part1: &mut Day5Part2, q: Vec) -> bool { + q.iter().enumerate().all(|(index, item)| { + part1.ordering.iter().filter(|order| { + order.left == *item + }).all(|order| { + index < q.iter().find_position(|x| { **x == order.right } ).or(Some((usize::MAX, &0))).unwrap().0 + }) + }) +} + fn solve_part2(part2: &mut Day5Part2) -> Result { - Ok(0) + let mut faulty = part2.queues.clone().into_iter().filter( + |q| { + !is_correct2(part2, q.clone()) + }).collect::>>(); + + let mut count = 0u64; + + for queue in faulty.iter_mut() { + loop { + let mut has_change = false; + for (index, item) in queue.clone().iter().enumerate() { + let all_entries = part2.ordering.iter().filter(|order| { order.left == *item}).collect::>(); + for entry in all_entries.iter() { + if let Some(pos) = queue.clone().iter_mut().position(|i| {*i == entry.right}) { + if pos < index { + has_change = true; + queue.insert(index+1, entry.right); + queue.remove(pos); + } + } + } + } + if !has_change { + break; + } + } + count += queue[queue.len() / 2] as u64; + } + Ok(count) }