From 3ece448fd86d231792dafffbf24ec40356940bca Mon Sep 17 00:00:00 2001 From: Jos van Goor Date: Sat, 21 Dec 2024 13:20:09 +0100 Subject: [PATCH] Day 8, Day9p1, updated solve_day macro --- advent_of_code_2024/src/day8/part1.rs | 54 ++++++++++++++- advent_of_code_2024/src/day8/part2.rs | 68 ++++++++++++++++++- advent_of_code_2024/src/day8/test.txt | 12 ++++ advent_of_code_2024/src/day8/test2.txt | 7 ++ advent_of_code_2024/src/day9/part1.rs | 75 ++++++++++++++++++++- advent_of_code_2024/src/day9/test.txt | 1 + advent_of_code_2024/src/main.rs | 20 +----- advent_of_code_2024/src/utility/solveday.rs | 44 ++++++------ 8 files changed, 239 insertions(+), 42 deletions(-) create mode 100644 advent_of_code_2024/src/day8/test.txt create mode 100644 advent_of_code_2024/src/day8/test2.txt create mode 100644 advent_of_code_2024/src/day9/test.txt diff --git a/advent_of_code_2024/src/day8/part1.rs b/advent_of_code_2024/src/day8/part1.rs index 8876943..a301028 100644 --- a/advent_of_code_2024/src/day8/part1.rs +++ b/advent_of_code_2024/src/day8/part1.rs @@ -1,3 +1,55 @@ +use std::collections::{HashMap, HashSet}; + +#[allow(unused)] +fn draw_antinodes(grid: &[&str], antinodes: &HashSet<(i64, i64)>) { + for (ypos, line) in grid.iter().enumerate() { + for (xpos, ch) in line.as_bytes().iter().enumerate() { + if antinodes.contains(&(xpos as i64, ypos as i64)) { + print!("#"); + } else { + print!("{}", *ch as char); + } + } + println!(); + } +} + +fn is_valid_node(width: i64, height: i64, node: (i64, i64)) -> bool{ + node.0 >= 0 && node.0 < width && node.1 >= 0 && node.1 < height +} + pub fn solve(input: &str) { - + let lines = input.lines().collect::>(); + let height = lines.len() as i64; + let width = lines[0].len() as i64; + + let mut antennas: HashMap> = HashMap::new(); + + for (ypos, line) in lines.iter().enumerate() { + for (xpos, object) in line.as_bytes().iter().enumerate() { + if *object != b'.' { + antennas.entry(*object).or_default().push((xpos as i64, ypos as i64)); + } + } + } + + let mut antinodes: HashSet<(i64, i64)> = HashSet::new(); + + for (_, antennas) in antennas.iter() { + for (idx, first) in antennas.iter().enumerate() { + for second in &antennas[(idx + 1)..] { + let dx = second.0 - first.0; + let dy = second.1 - first.1; + + if is_valid_node(width, height, (second.0 + dx, second.1 + dy)) { + antinodes.insert((second.0 + dx, second.1 + dy)); + } + if is_valid_node(width, height, (first.0 - dx, first.1 - dy)) { + antinodes.insert((first.0 - dx, first.1 - dy)); + } + } + } + } + + println!("# antinodes: {}", antinodes.len()); } \ No newline at end of file diff --git a/advent_of_code_2024/src/day8/part2.rs b/advent_of_code_2024/src/day8/part2.rs index 6197ad3..c43a671 100644 --- a/advent_of_code_2024/src/day8/part2.rs +++ b/advent_of_code_2024/src/day8/part2.rs @@ -1,4 +1,70 @@ +use std::collections::{HashMap, HashSet}; + +#[allow(unused)] +fn draw_antinodes(grid: &[&str], antinodes: &HashSet<(i64, i64)>) { + for (ypos, line) in grid.iter().enumerate() { + for (xpos, ch) in line.as_bytes().iter().enumerate() { + if antinodes.contains(&(xpos as i64, ypos as i64)) { + print!("#"); + } else { + print!("{}", *ch as char); + } + } + println!(); + } +} + +fn is_valid_node(width: i64, height: i64, node: (i64, i64)) -> bool{ + node.0 >= 0 && node.0 < width && node.1 >= 0 && node.1 < height +} + +fn calculate_node(start: &(i64, i64), delta: (i64, i64), step: i64) -> (i64, i64) { + (start.0 + delta.0 * step, start.1 + delta.1 * step) +} pub fn solve(input: &str) { - + let lines = input.lines().collect::>(); + let height = lines.len() as i64; + let width = lines[0].len() as i64; + + let mut antennas: HashMap> = HashMap::new(); + + for (ypos, line) in lines.iter().enumerate() { + for (xpos, object) in line.as_bytes().iter().enumerate() { + if *object != b'.' { + antennas.entry(*object).or_default().push((xpos as i64, ypos as i64)); + } + } + } + + let mut antinodes: HashSet<(i64, i64)> = HashSet::new(); + + for (_, antennas) in antennas.iter() { + for (idx, first) in antennas.iter().enumerate() { + for second in &antennas[(idx + 1)..] { + let dx = second.0 - first.0; + let dy = second.1 - first.1; + + for idx in 0i64.. { + let node = calculate_node(second, (dx, dy), idx); + if is_valid_node(width, height, node) { + antinodes.insert(node); + } else { + break; + } + } + + for idx in 0.. { + let node = calculate_node(first, (dx, dy), -idx); + if is_valid_node(width, height, node) { + antinodes.insert(node); + } else { + break; + } + } + } + } + } + + println!("# antinodes: {}", antinodes.len()); } \ No newline at end of file diff --git a/advent_of_code_2024/src/day8/test.txt b/advent_of_code_2024/src/day8/test.txt new file mode 100644 index 0000000..de0f909 --- /dev/null +++ b/advent_of_code_2024/src/day8/test.txt @@ -0,0 +1,12 @@ +............ +........0... +.....0...... +.......0.... +....0....... +......A..... +............ +............ +........A... +.........A.. +............ +............ \ No newline at end of file diff --git a/advent_of_code_2024/src/day8/test2.txt b/advent_of_code_2024/src/day8/test2.txt new file mode 100644 index 0000000..4e5ca35 --- /dev/null +++ b/advent_of_code_2024/src/day8/test2.txt @@ -0,0 +1,7 @@ +b.....a +....... +....... +c.....c +....... +....... +a.....b \ No newline at end of file diff --git a/advent_of_code_2024/src/day9/part1.rs b/advent_of_code_2024/src/day9/part1.rs index 8876943..24ed92b 100644 --- a/advent_of_code_2024/src/day9/part1.rs +++ b/advent_of_code_2024/src/day9/part1.rs @@ -1,3 +1,76 @@ +type Block = Option; + +fn print_uncompressed(fs: &[Block]) { + for (idx, block) in fs.iter().enumerate() { + match block { + Some(num) => print!("{}", num), + None => print!("."), + } + } + println!(); +} + +fn find_empty(fs: &[Block], start: usize) -> usize { + for (idx, block) in fs.iter().enumerate().skip(start) { + if block.is_none() { + return idx; + } + } + + fs.len() +} + +fn find_last_block(fs: &[Block], start: usize) -> usize { + for offset in 0usize.. { + let idx = start - offset; + if fs[idx].is_some() { + return idx; + } + } + + 0 +} + pub fn solve(input: &str) { + let compressed = input.as_bytes(); + let mut uncompressed: Vec = Vec::new(); + + let mut file_id = 0u64; + for (idx, byte) in compressed.iter().enumerate() { + let number = (byte - b'0') as usize; + if idx % 2 == 1 { + // free space + for _ in 0..number { + uncompressed.push(None); + } + } else { + for _ in 0..number { + uncompressed.push(Some(file_id)); + } + file_id += 1; + } + } -} \ No newline at end of file + let mut free_block = find_empty(&uncompressed, 0); + let mut last_block = find_last_block(&uncompressed, uncompressed.len() - 1); + // print!("len: {}, free: {:0>2}, last: {:0>2} - ", uncompressed.len(), free_block, last_block); + // print_uncompressed(&uncompressed); + + while free_block < last_block { + uncompressed[free_block] = uncompressed[last_block]; + uncompressed[last_block] = None; + + free_block = find_empty(&uncompressed, free_block); + last_block = find_last_block(&uncompressed, last_block); + } + + let mut checksum: u64 = 0; + for (idx, block) in uncompressed.iter().enumerate() { + match block { + Some(num) => checksum += num * (idx as u64), + None => break, + } + } + + println!("Filesystem checksum: {}", checksum); +} diff --git a/advent_of_code_2024/src/day9/test.txt b/advent_of_code_2024/src/day9/test.txt new file mode 100644 index 0000000..5ff5aae --- /dev/null +++ b/advent_of_code_2024/src/day9/test.txt @@ -0,0 +1 @@ +2333133121414131402 \ No newline at end of file diff --git a/advent_of_code_2024/src/main.rs b/advent_of_code_2024/src/main.rs index 5a84efa..e0c9e8d 100644 --- a/advent_of_code_2024/src/main.rs +++ b/advent_of_code_2024/src/main.rs @@ -1,22 +1,4 @@ use paste::paste; - -mod day1; -mod day2; -mod day3; -mod day4; -mod day5; -mod day6; -mod day7; -mod day8; -mod day9; mod utility; -pub fn main() { - solve_day!(1); - solve_day!(2); - solve_day!(3); - solve_day!(4); - solve_day!(5); - solve_day!(6); - solve_day!(7); -} +solve_day!(8); \ No newline at end of file diff --git a/advent_of_code_2024/src/utility/solveday.rs b/advent_of_code_2024/src/utility/solveday.rs index c711b6a..e0b627b 100644 --- a/advent_of_code_2024/src/utility/solveday.rs +++ b/advent_of_code_2024/src/utility/solveday.rs @@ -1,26 +1,30 @@ - #[macro_export] macro_rules! solve_day { - ( $day:literal ) => {{ - println!("-- Day {} --", $day); - let input = utility::get_input_string($day); - paste!{ [] ::part1::solve(&input) }; - paste!{ [] ::part2::solve(&input) }; - }} + ($day:literal) => { + paste! {mod [];} + + pub fn main() { + println!("-- Day {} --", $day); + let input = utility::get_input_string($day); + paste! { [] ::part1::solve(&input) }; + paste! { [] ::part2::solve(&input) }; + } + }; + ($day:literal, $filename:literal) => { + paste! {mod [];} + + pub fn main() { + println!("-- Day {} --", $day); + let input = utility::get_test_string($day, Some($filename)); + paste! { [] ::part1::solve(&input) }; + paste! { [] ::part2::solve(&input) }; + } + }; } #[macro_export] macro_rules! test_day { - ( $day:literal ) => {{ - println!("-- Day {} --", $day); - let input = utility::get_test_string($day, None); - paste!{ [] ::part1::solve(&input) }; - paste!{ [] ::part2::solve(&input) }; - }}; - ( $day:literal, $filename:literal ) => {{ - println!("-- Day {} --", $day); - let input = utility::get_test_string($day, Some($filename)); - paste!{ [] ::part1::solve(&input) }; - paste!{ [] ::part2::solve(&input) }; - }} -} \ No newline at end of file + ($day:literal) => { + solve_day!($day, "test.txt"); + }; +}