A input/day5/example => input/day5/example +28 -0
@@ 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
A src/day5/mod.rs => src/day5/mod.rs +115 -0
@@ 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<i32> {
+ 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::<i32>().unwrap())
+ .collect::<Vec<i32>>(),
+ )
+ } else {
+ pages_to_update.push(
+ line.split(",")
+ .map(|s| s.parse::<i32>().unwrap())
+ .collect::<Vec<i32>>(),
+ )
+ }
+ }
+
+ 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<i32>]) -> 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<i32> {
+ 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::<i32>().unwrap())
+ .collect::<Vec<i32>>(),
+ )
+ } else {
+ pages_to_update.push(
+ line.split(",")
+ .map(|s| s.parse::<i32>().unwrap())
+ .collect::<Vec<i32>>(),
+ )
+ }
+ }
+
+ 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<i32>]) -> Vec<i32> {
+ 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
+}
M src/main.rs => src/main.rs +8 -0
@@ 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(())