From 849a172cb5a7c9112602c0ef98510654801e2f15 Mon Sep 17 00:00:00 2001 From: Jonni Liljamo Date: Thu, 5 Dec 2024 10:38:34 +0200 Subject: [PATCH] feat: day5 --- input/day5/example | 28 +++++++++++ src/day5/mod.rs | 115 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 8 ++++ 3 files changed, 151 insertions(+) create mode 100644 input/day5/example create mode 100644 src/day5/mod.rs diff --git a/input/day5/example b/input/day5/example new file mode 100644 index 0000000..9d146d6 --- /dev/null +++ b/input/day5/example @@ -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 diff --git a/src/day5/mod.rs b/src/day5/mod.rs new file mode 100644 index 0000000..9f43158 --- /dev/null +++ b/src/day5/mod.rs @@ -0,0 +1,115 @@ +use std::{ + fs::File, + io::{BufRead, BufReader}, + path::Path, +}; + +pub fn solve(input: &Path) -> anyhow::Result<()> { + println!("part one: {}", part_one(input)?); + println!("part two: {}", part_two(input)?); + + Ok(()) +} + +fn part_one(input: &Path) -> anyhow::Result { + let reader = BufReader::new(File::open(input)?); + + let mut reading_rules = true; + let mut rules = vec![]; + let mut pages_to_update = vec![]; + for line in reader.lines() { + let line = line?; + if line.is_empty() { + reading_rules = false; + continue; + } + if reading_rules { + rules.push( + line.split("|") + .map(|s| s.parse::().unwrap()) + .collect::>(), + ) + } else { + pages_to_update.push( + line.split(",") + .map(|s| s.parse::().unwrap()) + .collect::>(), + ) + } + } + + let mut answer = 0; + for pages in pages_to_update { + if is_in_order(&pages, &rules) { + answer += pages[pages.len() / 2]; + } + } + Ok(answer) +} + +fn is_in_order(pages: &[i32], rules: &[Vec]) -> bool { + for (left_index, page) in pages.iter().enumerate() { + for rule in rules.iter().filter(|&r| r[0] == *page) { + if let Some(right_index) = pages.iter().position(|n| *n == rule[1]) { + if right_index < left_index { + return false; + } + } + } + } + true +} + +fn part_two(input: &Path) -> anyhow::Result { + let reader = BufReader::new(File::open(input)?); + + let mut reading_rules = true; + let mut rules = vec![]; + let mut pages_to_update = vec![]; + for line in reader.lines() { + let line = line?; + if line.is_empty() { + reading_rules = false; + continue; + } + if reading_rules { + rules.push( + line.split("|") + .map(|s| s.parse::().unwrap()) + .collect::>(), + ) + } else { + pages_to_update.push( + line.split(",") + .map(|s| s.parse::().unwrap()) + .collect::>(), + ) + } + } + + let mut answer = 0; + for pages in pages_to_update + .iter() + .filter(|pages| !is_in_order(pages, &rules)) + { + answer += ordered(pages, &rules)[pages.len() / 2]; + } + Ok(answer) +} + +fn ordered(pages: &[i32], rules: &[Vec]) -> Vec { + let mut pages = pages.to_owned(); + 'w: while !is_in_order(&pages, rules) { + for (left_index, page) in pages.iter().enumerate() { + for rule in rules.iter().filter(|&r| r[0] == *page) { + if let Some(right_index) = pages.iter().position(|n| *n == rule[1]) { + if right_index < left_index { + pages.swap(right_index, left_index); + continue 'w; + } + } + } + } + } + pages +} diff --git a/src/main.rs b/src/main.rs index 3f25480..e03647d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ mod day1; mod day2; mod day3; mod day4; +mod day5; #[derive(Parser)] struct Args { @@ -34,6 +35,10 @@ enum DayArgs { #[arg(short)] input: PathBuf, }, + Day5 { + #[arg(short)] + input: PathBuf, + }, } fn main() -> anyhow::Result<()> { @@ -52,6 +57,9 @@ fn main() -> anyhow::Result<()> { DayArgs::Day4 { input } => { day4::solve(&input)?; } + DayArgs::Day5 { input } => { + day5::solve(&input)?; + } } Ok(()) -- 2.44.1