mirror of
https://github.com/RussellChamp/advent-of-code-2024-rust.git
synced 2026-10-27 23:52:29 +00:00
day 5 pt1, day 6 pt1
This commit is contained in:
1 parent
d359b1cf99
commit
30b9e9e249
5 files changed
+259
No files matched your search
@@ -0,0 +1,28 @@
|
|||||||
|
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
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
....#.....
|
||||||
|
.........#
|
||||||
|
..........
|
||||||
|
..#.......
|
||||||
|
.......#..
|
||||||
|
..........
|
||||||
|
.#..^.....
|
||||||
|
........#.
|
||||||
|
#.........
|
||||||
|
......#...
|
||||||
@@ -294,6 +294,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn test_part_one() {
|
fn test_part_one() {
|
||||||
let result = part_one(&advent_of_code::template::read_file_part("examples", DAY, 99));
|
let result = part_one(&advent_of_code::template::read_file_part("examples", DAY, 99));
|
||||||
assert_eq!(result, Some(18));
|
assert_eq!(result, Some(18));
|
||||||
|
|||||||
+132
@@ -0,0 +1,132 @@
|
|||||||
|
// 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();
|
||||||
|
|
||||||
|
// println!("{} lines", rules.len());
|
||||||
|
|
||||||
|
// Parse the books
|
||||||
|
let books = reader.by_ref().take_while(|l| !l.is_empty()).map(|r| r.split(','));
|
||||||
|
|
||||||
|
// 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 is_valid = get_is_valid(&rules, &pages);
|
||||||
|
|
||||||
|
if is_valid {
|
||||||
|
let middle = pages.len() / 2;
|
||||||
|
let middle_val = pages[middle].parse::<u32>().unwrap();
|
||||||
|
// println!("{middle_val}");
|
||||||
|
|
||||||
|
valid_books_count += 1;
|
||||||
|
t + middle_val
|
||||||
|
} else {
|
||||||
|
t
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// println!("Total {}, value {}", valid_books_count, total);
|
||||||
|
Some(total)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(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();
|
||||||
|
|
||||||
|
// println!("{} lines", rules.len());
|
||||||
|
|
||||||
|
// Parse the books
|
||||||
|
let books = reader.by_ref().take_while(|l| !l.is_empty()).map(|r| r.split(','));
|
||||||
|
|
||||||
|
// 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 is_valid = get_is_valid(&rules, &pages);
|
||||||
|
|
||||||
|
if is_valid {
|
||||||
|
return t
|
||||||
|
} else {
|
||||||
|
// println!("Invalid pages {:?}", pages);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
// println!("Valid pages {:?}", valid_pages);
|
||||||
|
|
||||||
|
let middle = valid_pages.len() / 2;
|
||||||
|
let middle_val = valid_pages[middle].parse::<u32>().unwrap();
|
||||||
|
// println!("{middle_val}");
|
||||||
|
|
||||||
|
valid_books_count += 1;
|
||||||
|
t + middle_val
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// println!("Total {}, value {}", valid_books_count, total);
|
||||||
|
Some(total)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_is_valid(rules: &Vec<Vec<&str>>, pages: &Vec<&str>) -> bool {
|
||||||
|
for (page_a_idx, page_a) in pages.iter().enumerate() {
|
||||||
|
for page_b in &pages[page_a_idx..] {
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
let is_valid = get_is_valid(rules, &pages);
|
||||||
|
|
||||||
|
if remaining_pages.len() == 0 && is_valid {
|
||||||
|
|
||||||
|
return Some(pages)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn factorial(n: usize) -> Option<usize> {
|
||||||
|
(1..n).try_fold(n, usize::checked_mul)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, Some(143));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, Some(123));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
advent_of_code::solution!(6);
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<u32> {
|
||||||
|
let mut pos = (0 as isize, 0 as isize);
|
||||||
|
let mut dir = (-1 as isize, 0 as isize);
|
||||||
|
|
||||||
|
let grid = input.lines().enumerate().map(|(line_idx, line)| {
|
||||||
|
let chars = line.chars().enumerate().map(|(char_idx, char)| {
|
||||||
|
if char == '^' {
|
||||||
|
pos.0 = line_idx as isize;
|
||||||
|
pos.1 = char_idx as isize;
|
||||||
|
}
|
||||||
|
char
|
||||||
|
});
|
||||||
|
// println!("{:?}", chars);
|
||||||
|
chars.collect_vec()
|
||||||
|
}).collect_vec();
|
||||||
|
|
||||||
|
let mut visited = vec![vec![0; grid[0].len()]; grid.len()];
|
||||||
|
visited[pos.0 as usize][pos.1 as usize] = 1;
|
||||||
|
|
||||||
|
|
||||||
|
let is_valid_position = |(row_idx, col_idx)| {
|
||||||
|
(0..grid.len() as isize).contains(&row_idx) && (0..grid[0].len() as isize).contains(&col_idx)
|
||||||
|
};
|
||||||
|
|
||||||
|
loop {
|
||||||
|
println!("At {:?} going {:?}", pos, dir);
|
||||||
|
|
||||||
|
let new_pos = (pos.0 + dir.0, pos.1 + dir.1);
|
||||||
|
if !is_valid_position(new_pos) { break }
|
||||||
|
|
||||||
|
if grid[new_pos.0 as usize][new_pos.1 as usize] == '#' {
|
||||||
|
// if it is a blocker, turn 90deg
|
||||||
|
let directions = vec![(-1, 0), (0, 1), (1, 0), (0, -1), (-1, 0)];
|
||||||
|
let new_dir = *directions.iter().skip_while(|d| **d != dir).skip(1).next().unwrap();
|
||||||
|
dir.0 = new_dir.0;
|
||||||
|
dir.1 = new_dir.1;
|
||||||
|
} else {
|
||||||
|
// else move into the new position and mark it as entered
|
||||||
|
visited[new_pos.0 as usize][new_pos.1 as usize] += 1;
|
||||||
|
pos.0 = new_pos.0;
|
||||||
|
pos.1 = new_pos.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Made it out!");
|
||||||
|
|
||||||
|
Some(count_spaces(visited) as u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(input: &str) -> Option<u32> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_spaces(grid: Vec<Vec<i32>>) -> usize {
|
||||||
|
grid.iter().flat_map(|line: &Vec<_>| line.iter().filter(|v| v > &&0)).count()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_count_spaces() {
|
||||||
|
let grid = vec![
|
||||||
|
vec![1,2,3],
|
||||||
|
vec![0,0,0],
|
||||||
|
vec![1,0,0]
|
||||||
|
];
|
||||||
|
let result = count_spaces(grid);
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, Some(41));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
||||||
|
assert_eq!(result, Some(6));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user