Day 5 done
This commit is contained in:
parent
dc5e3b450f
commit
3d78aaee63
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::path::{Path, PathBuf};
|
|||
pub use std::{
|
||||
cmp::Ordering,
|
||||
collections::HashMap,
|
||||
collections::HashSet,
|
||||
fs::File,
|
||||
io::Read,
|
||||
iter::zip,
|
||||
|
|
Loading…
Reference in a new issue