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) {
|
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;
|
use paste::paste;
|
||||||
|
|
||||||
mod day1;
|
|
||||||
mod day2;
|
|
||||||
mod day3;
|
|
||||||
mod day4;
|
|
||||||
mod day5;
|
|
||||||
mod day6;
|
|
||||||
mod day7;
|
|
||||||
mod day8;
|
|
||||||
mod day9;
|
|
||||||
mod utility;
|
mod utility;
|
||||||
|
|
||||||
pub fn main() {
|
solve_day!(8);
|
||||||
solve_day!(1);
|
|
||||||
solve_day!(2);
|
|
||||||
solve_day!(3);
|
|
||||||
solve_day!(4);
|
|
||||||
solve_day!(5);
|
|
||||||
solve_day!(6);
|
|
||||||
solve_day!(7);
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +1,30 @@
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! solve_day {
|
macro_rules! solve_day {
|
||||||
( $day:literal ) => {{
|
($day:literal) => {
|
||||||
|
paste! {mod [<day $day>];}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
println!("-- Day {} --", $day);
|
println!("-- Day {} --", $day);
|
||||||
let input = utility::get_input_string($day);
|
let input = utility::get_input_string($day);
|
||||||
paste!{ [<day $day>] ::part1::solve(&input) };
|
paste! { [<day $day>] ::part1::solve(&input) };
|
||||||
paste!{ [<day $day>] ::part2::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_export]
|
||||||
macro_rules! test_day {
|
macro_rules! test_day {
|
||||||
( $day:literal ) => {{
|
($day:literal) => {
|
||||||
println!("-- Day {} --", $day);
|
solve_day!($day, "test.txt");
|
||||||
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) };
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue