mirror of
https://github.com/RussellChamp/advent-of-code-2024-rust.git
synced 2026-10-27 23:52:29 +00:00
day 5 pt2
This commit is contained in:
1 parent
6bd875f3fc
commit
54591fadd8
3 files changed
+51
-41
No files matched your search
+46
-37
@@ -1,11 +1,16 @@
|
||||
// use itertools::Itertools;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
advent_of_code::solution!(5);
|
||||
|
||||
pub fn part_one(input: &str) -> Option<u32> {
|
||||
// Parse the rules
|
||||
let mut reader = input.lines();
|
||||
let rules: Vec<_> = reader.by_ref().take_while(|l| !l.is_empty()).map(|r| r.split('|').collect::<Vec<&str>>()).collect();
|
||||
let rules = reader.by_ref().take_while(|l| !l.is_empty()).map(|r| {
|
||||
let pages = r.split('|').collect_vec();
|
||||
(pages[0].parse::<u32>().unwrap(), pages[1].parse::<u32>().unwrap())
|
||||
}).collect_vec();
|
||||
|
||||
// println!("{} lines", rules.len());
|
||||
|
||||
@@ -15,13 +20,13 @@ pub fn part_one(input: &str) -> Option<u32> {
|
||||
// Check each book against all the rules
|
||||
let mut valid_books_count = 0;
|
||||
let total = books.fold(0, |t, book| {
|
||||
let pages = book.collect::<Vec<&str>>();
|
||||
let pages = book.map(|s| s.parse::<u32>().unwrap()).collect_vec();
|
||||
|
||||
let is_valid = get_is_valid(&rules, &pages);
|
||||
|
||||
if is_valid {
|
||||
let middle = pages.len() / 2;
|
||||
let middle_val = pages[middle].parse::<u32>().unwrap();
|
||||
let middle_val = pages[middle];
|
||||
// println!("{middle_val}");
|
||||
|
||||
valid_books_count += 1;
|
||||
@@ -35,14 +40,14 @@ pub fn part_one(input: &str) -> Option<u32> {
|
||||
Some(total)
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
pub fn part_two(_input: &str) -> Option<u32> {
|
||||
// TODO: Fix this
|
||||
return None;
|
||||
|
||||
// Parse the rules
|
||||
let mut reader = _input.lines();
|
||||
let rules: Vec<_> = reader.by_ref().take_while(|l| !l.is_empty()).map(|r| r.split('|').collect::<Vec<&str>>()).collect();
|
||||
let rules = reader.by_ref().take_while(|l| !l.is_empty()).map(|r| {
|
||||
let pages = r.split('|').collect_vec();
|
||||
(pages[0].parse::<u32>().unwrap(), pages[1].parse::<u32>().unwrap())
|
||||
}).collect_vec();
|
||||
|
||||
// println!("{} lines", rules.len());
|
||||
|
||||
@@ -52,7 +57,7 @@ pub fn part_two(_input: &str) -> Option<u32> {
|
||||
// Check each book against all the rules
|
||||
let mut valid_books_count = 0;
|
||||
let total = books.fold(0, |t, book| {
|
||||
let pages = book.collect::<Vec<&str>>();
|
||||
let pages = book.map(|s| s.parse::<u32>().unwrap()).collect_vec();
|
||||
let is_valid = get_is_valid(&rules, &pages);
|
||||
|
||||
if is_valid {
|
||||
@@ -62,12 +67,12 @@ pub fn part_two(_input: &str) -> Option<u32> {
|
||||
|
||||
// build up a book one page at a time (starting with 2 pages) and
|
||||
// println!("Checking {} permutations of {:?}", factorial(pages.len()).unwrap(), pages);
|
||||
let valid_pages = find_valid_book(&rules, Vec::from([]), pages).unwrap();
|
||||
let valid_pages = order_book(&rules, pages);
|
||||
|
||||
// println!("Valid pages {:?}", valid_pages);
|
||||
|
||||
let middle = valid_pages.len() / 2;
|
||||
let middle_val = valid_pages[middle].parse::<u32>().unwrap();
|
||||
let middle_val = valid_pages[middle];
|
||||
// println!("{middle_val}");
|
||||
|
||||
valid_books_count += 1;
|
||||
@@ -79,45 +84,49 @@ pub fn part_two(_input: &str) -> Option<u32> {
|
||||
Some(total)
|
||||
}
|
||||
|
||||
fn get_is_valid(rules: &[Vec<&str>], pages: &[&str]) -> bool {
|
||||
for (page_a_idx, page_a) in pages.iter().enumerate() {
|
||||
for page_b in &pages[page_a_idx..] {
|
||||
fn get_is_valid(rules: &[(u32, u32)], pages: &[u32]) -> bool {
|
||||
pages.iter().combinations(2).all(|pages| {
|
||||
// check for a violation of the rules!
|
||||
let is_invalid = rules.iter().any(|r| r[0] == *page_b && r[1] == *page_a);
|
||||
if is_invalid { return false }
|
||||
}
|
||||
}
|
||||
true
|
||||
!rules.iter().any(|r| r.0 == *pages[1] && r.1 == *pages[0])
|
||||
})
|
||||
}
|
||||
|
||||
fn find_valid_book<'a>(rules: &Vec<Vec<&str>>, pages: Vec<&'a str>, remaining_pages: Vec<&'a str>) -> Option<Vec<&'a str>> {
|
||||
// println!("Checking {:?}", pages);
|
||||
fn order_book(rules: &[(u32, u32)], pages: Vec<u32>) -> Vec<u32> {
|
||||
let mut ordered_pages = vec![];
|
||||
|
||||
let is_valid = get_is_valid(rules, &pages);
|
||||
|
||||
if remaining_pages.is_empty() && is_valid {
|
||||
|
||||
return Some(pages)
|
||||
'page: for p in pages {
|
||||
for idx in 0..=ordered_pages.len() {
|
||||
let mut new_pages = ordered_pages.clone();
|
||||
new_pages.insert(idx, p);
|
||||
if get_is_valid(rules, new_pages.as_slice()) {
|
||||
ordered_pages.insert(idx, p);
|
||||
continue 'page;
|
||||
} else if idx == ordered_pages.len() {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !is_valid {
|
||||
// println!("INVALID! {:?} - Eliminating {} additional permutations", pages, factorial(remaining_pages.len()).unwrap());
|
||||
return None
|
||||
} // trim this branch
|
||||
|
||||
remaining_pages.iter().find_map(|rp| {
|
||||
let mut next_pages = pages.clone();
|
||||
next_pages.push(rp);
|
||||
let next_remaining_pages = remaining_pages.iter().cloned().filter(|p| p != rp).collect();
|
||||
|
||||
find_valid_book(rules, next_pages, next_remaining_pages)
|
||||
})
|
||||
ordered_pages
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_combinations() {
|
||||
let result = (1..=4).combinations(2);
|
||||
itertools::assert_equal(result, vec![
|
||||
vec![1, 2],
|
||||
vec![1, 3],
|
||||
vec![1, 4],
|
||||
vec![2, 3],
|
||||
vec![2, 4],
|
||||
vec![3, 4],
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_one() {
|
||||
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
||||
|
||||
+3
-2
@@ -61,7 +61,7 @@ pub fn part_two(_input: &str) -> Option<u32> {
|
||||
None
|
||||
}
|
||||
|
||||
fn run_program(registers: &mut Vec<usize>, program: Vec<u8>) -> Vec<usize> {
|
||||
fn run_program(registers: &mut [usize], program: Vec<u8>) -> Vec<usize> {
|
||||
let mut output: Vec<usize> = vec![];
|
||||
|
||||
let literal = |v: usize| v;
|
||||
@@ -183,9 +183,10 @@ mod tests {
|
||||
assert_eq!(result, Some("4,6,3,5,6,3,5,2,1,0".to_string()));
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_part_two() {
|
||||
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
||||
assert_eq!(result, None);
|
||||
assert_eq!(result, Some(117440));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user