This commit is contained in:
Fabian Schmidt 2024-12-05 09:13:24 +01:00
parent a141026754
commit fa52f5bd13
4 changed files with 1583 additions and 0 deletions

1380
y2024/resources/5_input.txt Normal file

File diff suppressed because it is too large Load Diff

20
y2024/src/bin/d5.rs Normal file
View File

@ -0,0 +1,20 @@
use std::fs;
use y2024::days::d5;
fn main() {
part1();
part2();
}
fn part1() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/5_input.txt")).unwrap();
println!("{}", d5::process_part1(&content));
}
fn part2() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/5_input.txt")).unwrap();
println!("{}", d5::process_part2(&content));
}

181
y2024/src/days/d5.rs Normal file
View File

@ -0,0 +1,181 @@
#[derive(Clone, Debug)]
struct Page {
number: u32,
before: Vec<u32>,
after: Vec<u32>,
}
fn get_page(rules: &[Page], page_num: u32) -> Option<(Page, usize)> {
for (rule_idx, rule) in rules.iter().enumerate() {
if rule.number == page_num {
return Some((rule.clone(), rule_idx));
}
}
None
}
pub fn process_part1(input: &str) -> u32 {
let mut rules = Vec::new();
let (rules_str, update) = input.split_once("\n\n").unwrap();
for rule in rules_str.lines() {
let (before, after) = rule.split_once("|").unwrap();
let before: u32 = before.parse().unwrap();
let after: u32 = after.parse().unwrap();
if let Some((mut page, page_idx)) = get_page(&rules, before) {
page.after.push(after);
rules[page_idx] = page;
} else {
rules.push(Page {
number: before,
before: Vec::new(),
after: vec![after],
});
}
if let Some((mut page, page_idx)) = get_page(&rules, after) {
page.before.push(before);
rules[page_idx] = page;
} else {
rules.push(Page {
number: after,
before: vec![before],
after: Vec::new(),
});
}
}
update
.lines()
.map(|pages| {
let mut visited = Vec::new();
let pages = pages
.split(",")
.map(|page| page.parse::<u32>().unwrap())
.collect::<Vec<u32>>();
for &page_num in pages.iter() {
let (page_rules, _) = get_page(&rules, page_num).unwrap();
for after in page_rules.after {
if visited.contains(&after) {
return 0;
}
}
visited.push(page_num);
}
pages[pages.len() / 2]
})
.sum()
}
pub fn process_part2(input: &str) -> u32 {
let mut rules = Vec::new();
let (rules_str, update) = input.split_once("\n\n").unwrap();
for rule in rules_str.lines() {
let (before, after) = rule.split_once("|").unwrap();
let before: u32 = before.parse().unwrap();
let after: u32 = after.parse().unwrap();
if let Some((mut page, page_idx)) = get_page(&rules, before) {
page.after.push(after);
rules[page_idx] = page;
} else {
rules.push(Page {
number: before,
before: Vec::new(),
after: vec![after],
});
}
if let Some((mut page, page_idx)) = get_page(&rules, after) {
page.before.push(before);
rules[page_idx] = page;
} else {
rules.push(Page {
number: after,
before: vec![before],
after: Vec::new(),
});
}
}
update
.lines()
.map(|pages| {
let mut visited = Vec::new();
let mut is_ordered = true;
let pages = pages
.split(",")
.map(|page| page.parse::<u32>().unwrap())
.collect::<Vec<u32>>();
'outer: for &page_num in pages.iter() {
let (page_rules, _) = get_page(&rules, page_num).unwrap();
for after in page_rules.after {
if visited.contains(&after) {
is_ordered = false;
break 'outer;
}
}
visited.push(page_num);
}
if !is_ordered {
let mut ordered_pages = Vec::new();
for &page_num in pages.iter() {
let (page_rules, _) = get_page(&rules, page_num).unwrap();
let mut page_idx = ordered_pages.len();
for after in page_rules.after {
if let Some(after_idx) =
ordered_pages.iter().position(|&page| page == after)
{
if page_idx > after_idx {
page_idx = after_idx;
}
}
}
ordered_pages.insert(page_idx, page_num);
}
return ordered_pages[ordered_pages.len() / 2];
}
0
})
.sum()
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &str = "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 part1() {
let result = process_part1(INPUT);
assert_eq!(result, 143);
}
#[test]
fn part2() {
let result = process_part2(INPUT);
assert_eq!(result, 123);
}
}

View File

@ -5,3 +5,5 @@ pub mod d2;
pub mod d3; pub mod d3;
pub mod d4; pub mod d4;
pub mod d5;