y2024d5
This commit is contained in:
parent
a141026754
commit
fa52f5bd13
1380
y2024/resources/5_input.txt
Normal file
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
20
y2024/src/bin/d5.rs
Normal 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
181
y2024/src/days/d5.rs
Normal 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);
|
||||
}
|
||||
}
|
@ -5,3 +5,5 @@ pub mod d2;
|
||||
pub mod d3;
|
||||
|
||||
pub mod d4;
|
||||
|
||||
pub mod d5;
|
||||
|
Loading…
Reference in New Issue
Block a user