Finish challenge 5

This commit is contained in:
Leon Grünewald 2024-12-12 02:48:10 +01:00
commit 91ac0a0688
4 changed files with 108 additions and 0 deletions

1
5/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

16
5/Cargo.lock generated Normal file
View file

@ -0,0 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
[[package]]
name = "aoc24-5"
version = "0.1.0"
dependencies = [
"anyhow",
]

7
5/Cargo.toml Normal file
View file

@ -0,0 +1,7 @@
[package]
name = "aoc24-5"
version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0"

84
5/src/main.rs Normal file
View file

@ -0,0 +1,84 @@
use std::fs::OpenOptions;
use std::io::Read;
use anyhow::bail;
fn get_data() -> anyhow::Result<String> {
let args = std::env::args();
// First argument is the executable, second argument is the path to our input.
if args.len() < 2 { bail!("Not enough arguments") }
let mut data = String::new();
{
let mut file = OpenOptions::new().read(true).open(args.last().expect("No file path"))?;
file.read_to_string(&mut data)?;
}
Ok(data)
}
fn parse_rules_and_updates(data: &String) -> (Vec<(&str, &str)>, Vec<Vec<&str>>){
let (rules, mut rest): (Vec<&str>, _) = data.lines()
.partition(|line| line.contains("|"));
let rules: Vec<(&str, &str)> = rules.into_iter()
.map(|rule| rule.split_once("|").expect("Could not split"))
.collect();
rest.drain(0..1);
let updates: Vec<Vec<&str>> = rest.into_iter()
.map(|page| page.split(",").collect())
.collect();
(rules, updates)
}
fn check_rule_compliance(update: &Vec<&str>, rule: &(&str, &str)) -> Option<(usize, usize)> {
let before_index_opt = update.iter().position(|elem| {*elem == rule.0});
let after_index_opt = update.iter().position(|elem| {*elem == rule.1});
match (before_index_opt, after_index_opt) {
(Some(before_index), Some(after_index)) => {
if before_index > after_index {
return Some((before_index, after_index));
}
}
_ => {
// println!("Skipping rule {rule:?}");
}
}
None
}
fn sum_middle_page_nums(updates: Vec<Vec<&str>>) -> i64 {
updates.iter()
.map(|update| update[update.len()/2])
.map(|middle| middle.parse::<i64>().unwrap())
.sum()
}
fn main() -> anyhow::Result<()> {
let data = get_data()?;
let (rules, updates) = parse_rules_and_updates(&data);
let mut correct_updates = Vec::new();
'update: for update in updates {
for rule in &rules {
if let Some(_) = check_rule_compliance(&update, rule) {
/*println!(
"Rule issue: {:?} ({before_index:?}) {:?} ({after_index:?})",
update[before_index],
update[after_index]
);
println!("Elements: {update:?}");*/
continue 'update;
}
}
correct_updates.push(update);
}
println!("{}", sum_middle_page_nums(correct_updates));
Ok(())
}