Day 8, Day9p1, updated solve_day macro

This commit is contained in:
Jos van Goor 2024-12-21 13:20:09 +01:00
parent 3c84d7232f
commit 3ece448fd8
8 changed files with 239 additions and 42 deletions

View file

@ -1,3 +1,55 @@
pub fn solve(input: &str) {
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::<Vec<_>>();
let height = lines.len() as i64;
let width = lines[0].len() as i64;
let mut antennas: HashMap<u8, Vec<(i64, i64)>> = 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());
}

View file

@ -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::<Vec<_>>();
let height = lines.len() as i64;
let width = lines[0].len() as i64;
let mut antennas: HashMap<u8, Vec<(i64, i64)>> = 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());
}

View file

@ -0,0 +1,12 @@
............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............

View file

@ -0,0 +1,7 @@
b.....a
.......
.......
c.....c
.......
.......
a.....b

View file

@ -1,3 +1,76 @@
pub fn solve(input: &str) {
type Block = Option<u64>;
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<Block> = 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;
}
}
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);
}

View file

@ -0,0 +1 @@
2333133121414131402

View file

@ -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);

View file

@ -1,26 +1,30 @@
#[macro_export]
macro_rules! solve_day {
( $day:literal ) => {{
println!("-- Day {} --", $day);
let input = utility::get_input_string($day);
paste!{ [<day $day>] ::part1::solve(&input) };
paste!{ [<day $day>] ::part2::solve(&input) };
}}
($day:literal) => {
paste! {mod [<day $day>];}
pub fn main() {
println!("-- Day {} --", $day);
let input = utility::get_input_string($day);
paste! { [<day $day>] ::part1::solve(&input) };
paste! { [<day $day>] ::part2::solve(&input) };
}
};
($day:literal, $filename:literal) => {
paste! {mod [<day $day>];}
pub fn main() {
println!("-- Day {} --", $day);
let input = utility::get_test_string($day, Some($filename));
paste! { [<day $day>] ::part1::solve(&input) };
paste! { [<day $day>] ::part2::solve(&input) };
}
};
}
#[macro_export]
macro_rules! test_day {
( $day:literal ) => {{
println!("-- Day {} --", $day);
let input = utility::get_test_string($day, None);
paste!{ [<day $day>] ::part1::solve(&input) };
paste!{ [<day $day>] ::part2::solve(&input) };
}};
( $day:literal, $filename:literal ) => {{
println!("-- Day {} --", $day);
let input = utility::get_test_string($day, Some($filename));
paste!{ [<day $day>] ::part1::solve(&input) };
paste!{ [<day $day>] ::part2::solve(&input) };
}}
($day:literal) => {
solve_day!($day, "test.txt");
};
}