feat(day5): init

This commit is contained in:
uku 2024-12-07 15:22:57 +01:00
parent 992756faa6
commit 6394c75524
Signed by: uku
SSH key fingerprint: SHA256:4P0aN6M8ajKukNi6aPOaX0LacanGYtlfjmN+m/sHY/o
2 changed files with 148 additions and 0 deletions

146
src/solutions/day_05.rs Normal file
View file

@ -0,0 +1,146 @@
use std::collections::{HashMap, HashSet};
use itertools::Itertools;
use crate::common::{Answer, Solution};
pub struct Day05;
impl Solution for Day05 {
fn name(&self) -> &'static str {
"Print Queue"
}
fn part_a(&self, input: &str) -> Answer {
let (rules, input) = input.split_once("\n\n").unwrap();
let rules = rules
.lines()
.map(|l| l.split_once("|").unwrap())
.map(|(a, b)| (a.parse::<u64>().unwrap(), b.parse::<u64>().unwrap()))
.into_grouping_map()
.collect::<HashSet<_>>();
let sum = input
.lines()
.map(|l| {
l.split(",")
.map(|n| n.parse::<u64>().unwrap())
.collect::<Vec<_>>()
})
.filter(|nums| is_ordered(nums, &rules))
.map(|nums| {
let middle = (nums.len() - 1) / 2;
nums[middle]
})
.sum::<u64>();
Answer::Number(sum)
}
fn part_b(&self, input: &str) -> Answer {
let (rules, input) = input.split_once("\n\n").unwrap();
let rules = rules
.lines()
.map(|l| l.split_once("|").unwrap())
.map(|(a, b)| (a.parse::<u64>().unwrap(), b.parse::<u64>().unwrap()))
.into_grouping_map()
.collect::<HashSet<_>>();
let sum = input
.lines()
.map(|l| {
l.split(",")
.map(|n| n.parse::<u64>().unwrap())
.collect::<Vec<_>>()
})
.filter(|nums| !is_ordered(nums, &rules))
.map(|mut nums| {
while !is_ordered(&nums, &rules) {
for (i, n) in nums.clone().iter().enumerate() {
let Some(rules) = rules.get(n) else {
continue;
};
let first_invalid = nums
.iter()
.enumerate()
.take(i)
.filter(|(_, n)| rules.contains(n))
.map(|(i2, _)| i2)
.next();
if let Some(i2) = first_invalid {
nums.swap(i, i2);
}
}
}
nums
})
.map(|nums| {
let middle = (nums.len() - 1) / 2;
nums[middle]
})
.sum::<u64>();
Answer::Number(sum)
}
}
fn is_ordered(nums: &[u64], rules: &HashMap<u64, HashSet<u64>>) -> bool {
nums.iter()
.enumerate()
.filter_map(|(i, n)| rules.get(n).map(|r| (i, r)))
.all(|(i, rules)| !nums.iter().take(i).any(|n| rules.contains(n)))
}
#[cfg(test)]
mod test {
use super::Day05;
use crate::common::Solution;
use indoc::indoc;
const INPUT: &str = indoc! {"
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
"};
#[test]
fn part_a() {
assert_eq!(Day05.part_a(INPUT), 143.into());
}
#[test]
fn part_b() {
assert_eq!(Day05.part_b(INPUT), 123.into());
}
}

View file

@ -4,10 +4,12 @@ mod day_01;
mod day_02; mod day_02;
mod day_03; mod day_03;
mod day_04; mod day_04;
mod day_05;
pub const SOLUTIONS: &[&dyn Solution] = &[ pub const SOLUTIONS: &[&dyn Solution] = &[
&day_01::Day01, &day_01::Day01,
&day_02::Day02, &day_02::Day02,
&day_03::Day03, &day_03::Day03,
&day_04::Day04, &day_04::Day04,
&day_05::Day05,
]; ];