day05
This commit is contained in:
parent
37a8d26f7f
commit
e955977bab
1364
src/day05/input.txt
Normal file
1364
src/day05/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
178
src/day05/mod.rs
Normal file
178
src/day05/mod.rs
Normal file
@ -0,0 +1,178 @@
|
||||
use std::{collections::HashMap, error::Error, fs};
|
||||
|
||||
/// Solves the problem for day 04.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function will return an error if the file cannot be read or if the input is invalid.
|
||||
#[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
|
||||
pub fn solve_day05(path: &str) -> Result<(i32, i32), Box<dyn Error>> {
|
||||
let content = fs::read_to_string(path)?;
|
||||
|
||||
let (rules, updates) = parse_input(&content);
|
||||
|
||||
let ordered_updates = updates
|
||||
.iter()
|
||||
.map(|update| order_updates(update, &rules))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let result_one = updates
|
||||
.iter()
|
||||
.zip(ordered_updates.iter())
|
||||
.filter(|(a, b)| a == b)
|
||||
.map(|(a, _)| a.clone())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let result_two = updates
|
||||
.iter()
|
||||
.zip(ordered_updates.iter())
|
||||
.filter(|(a, b)| a != b)
|
||||
.map(|(_, b)| b.clone())
|
||||
.collect::<Vec<_>>();
|
||||
let part_one = sum_middle_value(&result_one);
|
||||
let part_two = sum_middle_value(&result_two);
|
||||
Ok((part_one, part_two))
|
||||
}
|
||||
|
||||
fn parse_input(input: &str) -> (HashMap<i32, Vec<i32>>, Vec<Vec<i32>>) {
|
||||
let parts: Vec<_> = input.split("\n\n").collect();
|
||||
let mut map: HashMap<i32, Vec<i32>> = HashMap::new();
|
||||
parts[0].split('\n').for_each(|r| {
|
||||
let values = r
|
||||
.split('|')
|
||||
.map(|i| i.parse().unwrap())
|
||||
.collect::<Vec<i32>>();
|
||||
|
||||
let index = values[0];
|
||||
map.entry(index)
|
||||
.or_default()
|
||||
.append(values[1..].to_vec().as_mut());
|
||||
});
|
||||
// .collect();
|
||||
|
||||
let updates: Vec<Vec<i32>> = parts[1]
|
||||
.split('\n')
|
||||
.map(|r| r.split(',').map(|i| i.parse().unwrap()).collect())
|
||||
.collect();
|
||||
|
||||
(map, updates)
|
||||
}
|
||||
|
||||
fn order_updates(updates: &[i32], rules: &HashMap<i32, Vec<i32>>) -> Vec<i32> {
|
||||
if !updates.iter().any(|u| rules.contains_key(u)) {
|
||||
return updates.to_vec();
|
||||
}
|
||||
|
||||
let mut ordered_updates: Vec<i32> = updates.to_vec();
|
||||
|
||||
ordered_updates.sort_by(|a, b| {
|
||||
for (key, values) in rules {
|
||||
if a == key && values.contains(b) {
|
||||
return std::cmp::Ordering::Less;
|
||||
// } else if b == key && values.contains(a) {
|
||||
// return std::cmp::Ordering::Greater;
|
||||
// } else if a < b {
|
||||
// return std::cmp::Ordering::Less;
|
||||
// } else if a > b {
|
||||
// return std::cmp::Ordering::Greater;
|
||||
}
|
||||
}
|
||||
std::cmp::Ordering::Equal
|
||||
});
|
||||
ordered_updates
|
||||
}
|
||||
|
||||
fn sum_middle_value(input: &[Vec<i32>]) -> i32 {
|
||||
input
|
||||
.iter()
|
||||
.filter_map(|row| {
|
||||
if row.is_empty() || row.len() % 2 == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(row[row.len() / 2])
|
||||
}
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_input() {
|
||||
let input = "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
|
||||
29,13,75
|
||||
75,97,47,61,53
|
||||
61,13,29
|
||||
97,13,75,29,47";
|
||||
let (rules, updates) = parse_input(input);
|
||||
assert_eq!(rules.len(), 6);
|
||||
assert_eq!(rules[&47], vec![53, 13, 61, 29]);
|
||||
assert_eq!(rules[&53], vec![29, 13]);
|
||||
|
||||
assert_eq!(updates.len(), 6);
|
||||
assert_eq!(updates[0], vec![75, 47, 61, 53, 29]);
|
||||
|
||||
let sum = sum_middle_value(&updates);
|
||||
assert_eq!(sum, 61 + 53 + 13 + 47 + 13 + 75);
|
||||
|
||||
let want = vec![75, 29, 13];
|
||||
let got = order_updates(&updates[2], &rules);
|
||||
dbg!(&got, &updates[2]);
|
||||
assert_eq!(got, want);
|
||||
|
||||
let want = vec![97, 75, 47, 61, 53];
|
||||
let got = order_updates(&updates[3], &rules);
|
||||
dbg!(&got, &updates[3]);
|
||||
assert_eq!(got, want);
|
||||
|
||||
let want = vec![61, 29, 13];
|
||||
let got = order_updates(&updates[4], &rules);
|
||||
dbg!(&got, &updates[4]);
|
||||
assert_eq!(got, want);
|
||||
|
||||
let want = vec![97, 75, 47, 29, 13];
|
||||
let got = order_updates(&updates[5], &rules);
|
||||
dbg!(&got, &want, &updates[5]);
|
||||
assert_eq!(got, want);
|
||||
|
||||
let want = 61;
|
||||
let got = sum_middle_value(&[order_updates(&updates[0], &rules)]);
|
||||
assert_eq!(got, want);
|
||||
|
||||
let want = 143;
|
||||
let got = sum_middle_value(
|
||||
&updates
|
||||
.iter()
|
||||
.take(3)
|
||||
.map(|u| order_updates(u, &rules))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
assert_eq!(got, want);
|
||||
}
|
||||
}
|
@ -2,3 +2,4 @@ pub mod day01;
|
||||
pub mod day02;
|
||||
pub mod day03;
|
||||
pub mod day04;
|
||||
pub mod day05;
|
||||
|
15
src/main.rs
15
src/main.rs
@ -1,5 +1,6 @@
|
||||
use adventofcode_24::{
|
||||
day01::solve_day01, day02::solve_day02, day03::solve_day03, day04::solve_day04,
|
||||
day05::solve_day05,
|
||||
};
|
||||
use clap::{Arg, Command};
|
||||
|
||||
@ -28,6 +29,11 @@ fn main() {
|
||||
.short('4')
|
||||
.help("Path to Day 04 Input file"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("day05")
|
||||
.short('5')
|
||||
.help("Path to Day 05 Input file"),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
if let Some(file) = matches.get_one::<String>("day01") {
|
||||
@ -67,4 +73,13 @@ fn main() {
|
||||
Err(e) => eprintln!("{e}"),
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(file) = matches.get_one::<String>("day05") {
|
||||
match solve_day05(file) {
|
||||
Ok((r1, r2)) => {
|
||||
println!("Result of Day 05:\nOrdered middle page count: {r1}\nPart two: {r2}");
|
||||
}
|
||||
Err(e) => eprintln!("{e}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user