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 d3;
|
||||||
|
|
||||||
pub mod d4;
|
pub mod d4;
|
||||||
|
|
||||||
|
pub mod d5;
|
||||||
|
Loading…
Reference in New Issue
Block a user