Day 5 done

This commit is contained in:
Daniel Flanagan 2024-12-05 11:17:53 -06:00
parent dc5e3b450f
commit 3d78aaee63
2 changed files with 91 additions and 7 deletions

View file

@ -1,16 +1,16 @@
mod prelude;
pub use crate::prelude::*;
fn main() {
let input = day_input(5);
let update: ManualUpdate = input.parse().unwrap();
println!("{update:?}");
show_answers(0, 0);
show_answers(update.part1(), update.part2());
}
#[derive(Debug)]
struct ManualUpdate {
rules: HashMap<i64, Vec<i64>>,
rules: HashMap<i64, HashSet<i64>>,
updates: Vec<Vec<i64>>,
}
@ -19,16 +19,15 @@ impl FromStr for ManualUpdate {
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (rules_string, updates_string) = s.split_once("\n\n").unwrap();
let mut rules: HashMap<i64, Vec<i64>> = HashMap::new();
let mut rules: HashMap<i64, HashSet<i64>> = HashMap::new();
let mut updates = vec![];
for rule in rules_string.lines() {
let (left, right) = rule.split_once("|").unwrap();
let (left, right): (i64, i64) = (left.parse()?, right.parse()?);
rules.entry(left).or_default().push(right);
rules.entry(left).or_default().insert(right);
}
for update in updates_string.lines() {
println!("{update}");
updates.push(
update
.split(",")
@ -41,10 +40,94 @@ impl FromStr for ManualUpdate {
}
}
impl ManualUpdate {
fn part1(&self) -> i64 {
self.updates
.iter()
.filter(|update| self.is_update_valid(update))
.map(Self::middle_page_number)
.sum()
}
fn part2(&self) -> i64 {
self.updates
.iter()
.filter(|update| !self.is_update_valid(update))
.map(|update| self.sort_update(update))
.map(|sorted_update| Self::middle_page_number(&sorted_update))
.sum()
}
fn middle_page_number(update: &Vec<i64>) -> i64 {
update[update.len() / 2]
}
fn is_update_valid(&self, update: &Vec<i64>) -> bool {
// work through pages in an update backwards
for (i, page) in update.iter().rev().enumerate() {
// so we can loop through each previous page
for previous_page in update[0..update.len() - i].iter().rev() {
if let Some(failure_pages) = self.rules.get(page) {
if failure_pages.contains(previous_page) {
return false;
}
}
}
}
return true;
}
fn sort_update(&self, update: &Vec<i64>) -> Vec<i64> {
let mut sorted_update = update.clone();
sorted_update.sort_by(|a, b| {
if let Some(after_pages) = self.rules.get(a) {
if after_pages.contains(b) {
return Ordering::Less;
}
}
return Ordering::Greater;
});
sorted_update
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {}
fn test() {
let manual_update: ManualUpdate = "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"
.parse()
.unwrap();
assert_eq!(manual_update.part1(), 143);
assert_eq!(manual_update.part2(), 123);
}
}

View file

@ -2,6 +2,7 @@ use std::path::{Path, PathBuf};
pub use std::{
cmp::Ordering,
collections::HashMap,
collections::HashSet,
fs::File,
io::Read,
iter::zip,