feat: day 8
This commit is contained in:
parent
e01ba930ff
commit
1e9030960d
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[features]
|
||||
full = ["day1", "day2", "day3", "day4", "day5", "day6", "day7"]
|
||||
full = ["day1", "day2", "day3", "day4", "day5", "day6", "day7", "day8"]
|
||||
default = ["full"]
|
||||
day1 = []
|
||||
day2 = []
|
||||
|
@ -13,6 +13,7 @@ day4 = []
|
|||
day5 = []
|
||||
day6 = []
|
||||
day7 = []
|
||||
day8 = []
|
||||
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
12
inputs/day08/example.txt
Normal file
12
inputs/day08/example.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
............
|
||||
........0...
|
||||
.....0......
|
||||
.......0....
|
||||
....0.......
|
||||
......A.....
|
||||
............
|
||||
............
|
||||
........A...
|
||||
.........A..
|
||||
............
|
||||
............
|
188
src/day08.rs
Normal file
188
src/day08.rs
Normal file
|
@ -0,0 +1,188 @@
|
|||
#![allow(clippy::cast_sign_loss, clippy::cast_possible_wrap)]
|
||||
use std::collections::HashSet;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
pub fn pt1(input: &str) -> usize {
|
||||
let char_positions = input
|
||||
.lines()
|
||||
.map(str::chars)
|
||||
.enumerate()
|
||||
.flat_map(|(y, line)| line.enumerate().map(move |(x, char)| (char, x, y)))
|
||||
.collect::<Vec<_>>();
|
||||
let dims = (input.lines().next().unwrap().len(), input.lines().count());
|
||||
debug!("dims: {dims:?}");
|
||||
let node_positions = char_positions
|
||||
.iter()
|
||||
.filter(|(c, _, _)| *c != '.')
|
||||
.collect::<Vec<_>>();
|
||||
let unique_nodes = node_positions
|
||||
.iter()
|
||||
.map(|(c, _, _)| *c)
|
||||
.collect::<HashSet<_>>();
|
||||
let mut antinode_positions = HashSet::<(usize, usize)>::new();
|
||||
for node in unique_nodes {
|
||||
let matching_node_positions = node_positions
|
||||
.iter()
|
||||
.filter(|(c, _, _)| *c == node)
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter();
|
||||
for (_, node_x, node_y) in matching_node_positions.clone() {
|
||||
for (_, other_node_x, other_node_y) in matching_node_positions.clone() {
|
||||
trace!(
|
||||
"comparing ({node_x}, {node_y}) with ({other_node_x}, {other_node_y}): {:?}, {:?}",
|
||||
node_x.cmp(other_node_x), node_y.cmp(other_node_y)
|
||||
);
|
||||
if node_x == other_node_x && node_y == other_node_y {
|
||||
continue;
|
||||
}
|
||||
let dx = *node_x as isize - *other_node_x as isize;
|
||||
let dy = *node_y as isize - *other_node_y as isize;
|
||||
let prev_x = *node_x as isize + dx;
|
||||
let prev_y = *node_y as isize + dy;
|
||||
let post_x = *other_node_x as isize - dx;
|
||||
let post_y = *other_node_y as isize - dy;
|
||||
if prev_x >= 0
|
||||
&& (prev_x as usize) < dims.0
|
||||
&& prev_y >= 0
|
||||
&& (prev_y as usize) < dims.1
|
||||
{
|
||||
antinode_positions.insert((prev_x as usize, prev_y as usize));
|
||||
}
|
||||
if post_x >= 0
|
||||
&& (post_x as usize) < dims.0
|
||||
&& post_y >= 0
|
||||
&& (post_y as usize) < dims.1
|
||||
{
|
||||
antinode_positions.insert((post_x as usize, post_y as usize));
|
||||
}
|
||||
}
|
||||
}
|
||||
debug!("antinodes for {node}: {antinode_positions:?}");
|
||||
}
|
||||
let new_map = input
|
||||
.lines()
|
||||
.enumerate()
|
||||
.map(|(y, line)| {
|
||||
line.chars()
|
||||
.enumerate()
|
||||
.map(|(x, c)| {
|
||||
if c != '.' || !antinode_positions.contains(&(x, y)) {
|
||||
c
|
||||
} else {
|
||||
'#'
|
||||
}
|
||||
})
|
||||
.collect::<String>()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
debug!("new Map: \n{new_map}");
|
||||
antinode_positions.len()
|
||||
}
|
||||
// 225 is too high
|
||||
pub fn pt2(input: &str) -> usize {
|
||||
let char_positions = input
|
||||
.lines()
|
||||
.map(str::chars)
|
||||
.enumerate()
|
||||
.flat_map(|(y, line)| line.enumerate().map(move |(x, char)| (char, x, y)))
|
||||
.collect::<Vec<_>>();
|
||||
let dims = (input.lines().next().unwrap().len(), input.lines().count());
|
||||
debug!("dims: {dims:?}");
|
||||
let node_positions = char_positions
|
||||
.iter()
|
||||
.filter(|(c, _, _)| *c != '.')
|
||||
.collect::<Vec<_>>();
|
||||
let unique_nodes = node_positions
|
||||
.iter()
|
||||
.map(|(c, _, _)| *c)
|
||||
.collect::<HashSet<_>>();
|
||||
let mut antinode_positions = HashSet::<(usize, usize)>::new();
|
||||
for node in unique_nodes {
|
||||
let matching_node_positions = node_positions
|
||||
.iter()
|
||||
.filter(|(c, _, _)| *c == node)
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter();
|
||||
for (_, node_x, node_y) in matching_node_positions.clone() {
|
||||
for (_, other_node_x, other_node_y) in matching_node_positions.clone() {
|
||||
trace!(
|
||||
"comparing ({node_x}, {node_y}) with ({other_node_x}, {other_node_y}): {:?}, {:?}",
|
||||
node_x.cmp(other_node_x), node_y.cmp(other_node_y)
|
||||
);
|
||||
if node_x == other_node_x && node_y == other_node_y {
|
||||
continue;
|
||||
}
|
||||
let dx = *node_x as isize - *other_node_x as isize;
|
||||
let dy = *node_y as isize - *other_node_y as isize;
|
||||
let mut prev_x = *node_x as isize;
|
||||
let mut prev_y = *node_y as isize;
|
||||
while prev_x >= 0
|
||||
&& (prev_x as usize) < dims.0
|
||||
&& prev_y >= 0
|
||||
&& (prev_y as usize) < dims.1
|
||||
{
|
||||
antinode_positions.insert((prev_x as usize, prev_y as usize));
|
||||
prev_x += dx;
|
||||
prev_y += dy;
|
||||
}
|
||||
let mut post_x = *other_node_x as isize;
|
||||
let mut post_y = *other_node_y as isize;
|
||||
while post_x >= 0
|
||||
&& (post_x as usize) < dims.0
|
||||
&& post_y >= 0
|
||||
&& (post_y as usize) < dims.1
|
||||
{
|
||||
antinode_positions.insert((post_x as usize, post_y as usize));
|
||||
post_x -= dx;
|
||||
post_y -= dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
debug!("antinodes for {node}: {antinode_positions:?}");
|
||||
}
|
||||
let new_map = input
|
||||
.lines()
|
||||
.enumerate()
|
||||
.map(|(y, line)| {
|
||||
line.chars()
|
||||
.enumerate()
|
||||
.map(|(x, c)| {
|
||||
if c != '.' || !antinode_positions.contains(&(x, y)) {
|
||||
c
|
||||
} else {
|
||||
'#'
|
||||
}
|
||||
})
|
||||
.collect::<String>()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
debug!("new Map: \n{new_map}");
|
||||
antinode_positions.len()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use tracing_test::traced_test;
|
||||
|
||||
use super::{pt1, pt2};
|
||||
use std::fs::read_to_string;
|
||||
|
||||
#[traced_test]
|
||||
#[test]
|
||||
pub fn test_pt1() {
|
||||
let input =
|
||||
read_to_string("./inputs/day08/example.txt").expect("Missing example.txt for day08");
|
||||
assert_eq!(pt1(&input), 14)
|
||||
}
|
||||
|
||||
#[traced_test]
|
||||
#[test]
|
||||
pub fn test_pt2() {
|
||||
let input =
|
||||
read_to_string("./inputs/day08/example.txt").expect("Missing example.txt for day08");
|
||||
|
||||
assert_eq!(pt2(&input), 34)
|
||||
}
|
||||
}
|
18
src/main.rs
18
src/main.rs
|
@ -1,5 +1,8 @@
|
|||
use std::{fmt::Display, fs::read_to_string, time::Instant};
|
||||
|
||||
use color_eyre::eyre;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
#[cfg(feature = "day1")]
|
||||
mod day01;
|
||||
#[cfg(feature = "day2")]
|
||||
|
@ -14,10 +17,14 @@ mod day05;
|
|||
mod day06;
|
||||
#[cfg(feature = "day7")]
|
||||
mod day07;
|
||||
#[cfg(feature = "day8")]
|
||||
mod day08;
|
||||
|
||||
fn main() {
|
||||
color_eyre::install().unwrap();
|
||||
tracing_subscriber::fmt().init();
|
||||
fn main() -> eyre::Result<()> {
|
||||
color_eyre::install()?;
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(EnvFilter::from_default_env())
|
||||
.init();
|
||||
#[cfg(feature = "day1")]
|
||||
solve_day(1, day01::pt1, day01::pt2);
|
||||
#[cfg(feature = "day2")]
|
||||
|
@ -32,6 +39,9 @@ fn main() {
|
|||
solve_day(6, day06::pt1, day06::pt2);
|
||||
#[cfg(feature = "day7")]
|
||||
solve_day(7, day07::pt1, day07::pt2);
|
||||
#[cfg(feature = "day8")]
|
||||
solve_day(8, day08::pt1, day08::pt2);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn solve_day<Fa, Fb, Ta, Tb>(day: u8, part_a: Fa, part_b: Fb)
|
||||
|
@ -52,6 +62,6 @@ where
|
|||
}
|
||||
Err(_) => {
|
||||
tracing::warn!("could not open ./inputs/day{day:02}/input.txt");
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue