Day 8, Day9p1, updated solve_day macro
This commit is contained in:
parent
3c84d7232f
commit
3ece448fd8
8 changed files with 239 additions and 42 deletions
|
|
@ -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());
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
12
advent_of_code_2024/src/day8/test.txt
Normal file
12
advent_of_code_2024/src/day8/test.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
............
|
||||
........0...
|
||||
.....0......
|
||||
.......0....
|
||||
....0.......
|
||||
......A.....
|
||||
............
|
||||
............
|
||||
........A...
|
||||
.........A..
|
||||
............
|
||||
............
|
||||
7
advent_of_code_2024/src/day8/test2.txt
Normal file
7
advent_of_code_2024/src/day8/test2.txt
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
b.....a
|
||||
.......
|
||||
.......
|
||||
c.....c
|
||||
.......
|
||||
.......
|
||||
a.....b
|
||||
|
|
@ -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);
|
||||
}
|
||||
1
advent_of_code_2024/src/day9/test.txt
Normal file
1
advent_of_code_2024/src/day9/test.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
2333133121414131402
|
||||
|
|
@ -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);
|
||||
|
|
@ -1,26 +1,30 @@
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! solve_day {
|
||||
( $day:literal ) => {{
|
||||
($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) };
|
||||
}}
|
||||
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");
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue