Finish challenge 5
This commit is contained in:
commit
91ac0a0688
4 changed files with 108 additions and 0 deletions
1
5/.gitignore
vendored
Normal file
1
5/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
16
5/Cargo.lock
generated
Normal file
16
5/Cargo.lock
generated
Normal 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
7
5/Cargo.toml
Normal 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
84
5/src/main.rs
Normal 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(())
|
||||
}
|
||||
|
||||
|
Loading…
Reference in a new issue