diff --git a/inputs/day05/example.txt b/inputs/day05/example.txt new file mode 100644 index 0000000..d4d4441 --- /dev/null +++ b/inputs/day05/example.txt @@ -0,0 +1,28 @@ +47|53 +97|13 +97|61 +97|47 +75|29 +61|13 +75|53 +29|13 +97|29 +53|29 +61|53 +97|53 +61|29 +47|13 +75|47 +97|75 +47|61 +75|61 +47|29 +75|13 +53|13 + +75,47,61,53,29 +97,61,53,29,13 +75,29,13 +75,97,47,61,53 +61,13,29 +97,13,75,29,47 \ No newline at end of file diff --git a/src/day04.rs b/src/day04.rs index bd70fa9..54892b7 100644 --- a/src/day04.rs +++ b/src/day04.rs @@ -123,7 +123,7 @@ mod tests { #[test] pub fn test_pt2() { let input = - read_to_string("./inputs/day04/example.txt").expect("Missing example_2.txt for day04"); + read_to_string("./inputs/day04/example.txt").expect("Missing example.txt for day04"); assert_eq!(pt2(&input), 9) } diff --git a/src/day05.rs b/src/day05.rs new file mode 100644 index 0000000..4ba63fc --- /dev/null +++ b/src/day05.rs @@ -0,0 +1,110 @@ +pub fn pt1(input: &str) -> usize { + let (ordering_rules, update) = input.split_once("\n\n").unwrap(); + let ordering_rules = ordering_rules + .lines() + .map(|line| line.split_once('|').unwrap()) + .map(|(a, b)| (a.parse::().unwrap(), b.parse::().unwrap())) + .collect::>(); + + let updates = update + .lines() + .map(|line| { + line.split(',') + .map(str::parse::) + .map(Result::unwrap) + .collect::>() + }) + .collect::>(); + updates + .iter() + .filter(is_update_sorted(ordering_rules)) + .map(|update| update[update.len() / 2]) + .sum() +} + +fn is_update_sorted(ordering_rules: Vec<(usize, usize)>) -> impl FnMut(&&Vec) -> bool { + move |update| { + ordering_rules.iter().all(|(a, b)| { + if update.contains(a) && update.contains(b) { + update.iter().position(|u| u == a).unwrap() + < update.iter().position(|u| u == b).unwrap() + } else { + true + } + }) + } +} + +pub fn pt2(input: &str) -> usize { + let (ordering_rules, update) = input.split_once("\n\n").unwrap(); + let ordering_rules = ordering_rules + .lines() + .map(|line| line.split_once('|').unwrap()) + .map(|(a, b)| (a.parse::().unwrap(), b.parse::().unwrap())) + .collect::>(); + + let updates = update + .lines() + .map(|line| { + line.split(',') + .map(str::parse::) + .map(Result::unwrap) + .collect::>() + }) + .collect::>(); + updates + .iter() + .filter(|update| { + ordering_rules.iter().any(|(a, b)| { + if update.contains(a) && update.contains(b) { + update.iter().position(|u| u == a).unwrap() + > update.iter().position(|u| u == b).unwrap() + } else { + false + } + }) + }) + .map(|update| { + let mut ordered_update = update.clone(); + let mut sorting_round = 0; + while !is_update_sorted(ordering_rules.clone())(&&ordered_update) { + sorting_round += 1; + tracing::debug!("Round {sorting_round}"); + for (a, b) in &ordering_rules { + if ordered_update.contains(a) + && ordered_update.contains(b) + && ordered_update.iter().position(|u| u == a).unwrap() + > ordered_update.iter().position(|u| u == b).unwrap() + { + let pos_x = ordered_update.iter().position(|u| u == a).unwrap(); + let pos_y = ordered_update.iter().position(|u| u == b).unwrap(); + ordered_update.swap(pos_x, pos_y); + }; + } + } + ordered_update + }) + .map(|update| update[update.len() / 2]) + .sum() +} + +#[cfg(test)] +mod tests { + use std::fs::read_to_string; + + use super::{pt1, pt2}; + + #[test] + pub fn test_pt1() { + let input = + read_to_string("./inputs/day05/example.txt").expect("Missing example.txt for day05"); + assert_eq!(pt1(&input), 143) + } + #[test] + pub fn test_pt2() { + let input = + read_to_string("./inputs/day05/example.txt").expect("Missing example.txt for day05"); + + assert_eq!(pt2(&input), 123) + } +} diff --git a/src/main.rs b/src/main.rs index b89e736..04529fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,8 @@ mod day01; mod day02; mod day03; mod day04; +mod day05; + fn main() { color_eyre::install().unwrap(); tracing_subscriber::fmt::init(); @@ -11,6 +13,7 @@ fn main() { solve_day(2, day02::pt1, day02::pt2); solve_day(3, day03::pt1, day03::pt2); solve_day(4, day04::pt1, day04::pt2); + solve_day(5, day05::pt1, day05::pt2); } fn solve_day(day: u8, part_a: Fa, part_b: Fb)