Compare commits

...

2 commits

Author SHA1 Message Date
Rh4096
68e14d9ef6 optimization 2024-12-10 14:05:39 +07:00
Rh4096
a0653a8223 day 10 2024-12-10 14:00:12 +07:00
4 changed files with 149 additions and 8 deletions

View file

@ -30,7 +30,8 @@ fn main() -> Result<()> {
6 => AocDaySixSolution, 6 => AocDaySixSolution,
7 => AocDaySevenSolution, 7 => AocDaySevenSolution,
8 => AocDayEightSolution, 8 => AocDayEightSolution,
9 => AocDayNineSolution 9 => AocDayNineSolution,
10 => AocDayTenSolution,
}; };
Ok(()) Ok(())

View file

@ -1,8 +1,120 @@
use std::{fs::read_to_string, path::Path}; use std::{
collections::{HashMap, HashSet},
fs::read_to_string,
path::Path,
};
use super::AocSolution; use super::AocSolution;
use crate::utils::Result; use crate::utils::{coord::Coord as Crd, Result};
type Coord = Crd<i8>;
struct HikingMap {
pub starting_points: Vec<Coord>,
pub mountain: HashMap<Coord, u8>,
}
impl HikingMap {
fn new(src: &str) -> Self {
let (starting_points, mountain) = src
.lines()
.zip(0..)
.flat_map(|(line, y)| {
line.chars().zip(0..).filter_map(move |(ch, x)| match ch {
'0' => Some((Coord::new(x, y), 0)),
'1' => Some((Coord::new(x, y), 1)),
'2' => Some((Coord::new(x, y), 2)),
'3' => Some((Coord::new(x, y), 3)),
'4' => Some((Coord::new(x, y), 4)),
'5' => Some((Coord::new(x, y), 5)),
'6' => Some((Coord::new(x, y), 6)),
'7' => Some((Coord::new(x, y), 7)),
'8' => Some((Coord::new(x, y), 8)),
'9' => Some((Coord::new(x, y), 9)),
_ => None,
})
})
.fold(
(Vec::new(), HashMap::new()),
|(mut spos, mut map), (coord, heigh)| {
if heigh == 0 {
spos.push(coord);
}
map.insert(coord, heigh);
(spos, map)
},
);
Self {
starting_points,
mountain,
}
}
fn hike(&self) -> u64 {
fn _inner(map: &HashMap<Coord, u8>, start_pos: Coord) -> u64 {
fn _traverse(map: &HashMap<Coord, u8>, summits: &mut HashSet<Coord>, current: Coord) {
if map.get(&current).is_some_and(|h| h == &9) {
summits.insert(current);
return;
}
for dir in current.surround() {
if map.get(&dir).is_some_and(|&h| map[&current] + 1 == h) {
_traverse(map, summits, dir);
}
}
}
let mut visited = HashSet::new();
if map.contains_key(&start_pos) {
_traverse(map, &mut visited, start_pos);
visited.len() as u64
} else {
0
}
}
self.starting_points
.iter()
.map(|pos| _inner(&self.mountain, *pos))
.sum()
}
fn hike_ver_two(&self) -> u64 {
fn _inner(map: &HashMap<Coord, u8>, start_pos: Coord) -> u64 {
fn _traverse(map: &HashMap<Crd<i8>, u8>, current: Coord, rate: &mut u64) {
if map.get(&current).is_some_and(|h| h == &9) {
*rate += 1;
return;
}
for dir in current.surround() {
if map.get(&dir).is_some_and(|&h| map[&current] + 1 == h) {
_traverse(map, dir, rate);
}
}
}
let mut rating = 0;
if map.contains_key(&start_pos) {
_traverse(map, start_pos, &mut rating);
rating
} else {
0
}
}
self.starting_points
.iter()
.map(|pos| _inner(&self.mountain, *pos))
.sum()
}
}
#[derive(Clone, Copy)]
pub struct AocDayTenSolution; pub struct AocDayTenSolution;
impl AocSolution for AocDayTenSolution { impl AocSolution for AocDayTenSolution {
@ -11,15 +123,17 @@ impl AocSolution for AocDayTenSolution {
fn get_input(&self, path: Option<&Path>) -> Result<String> { fn get_input(&self, path: Option<&Path>) -> Result<String> {
Ok(match path { Ok(match path {
Some(p) => read_to_string(p)?, Some(p) => read_to_string(p)?,
None => read_to_string("./input/day_day_10.txt")?, None => read_to_string("./input/day_10.txt")?,
}) })
} }
fn part_one(&self, input: &str) -> Result<Self::Output> { fn part_one(&self, input: &str) -> Result<Self::Output> {
todo!() let map = HikingMap::new(input);
Ok(map.hike())
} }
fn part_two(&self, input: &str) -> Result<Self::Output> { fn part_two(&self, input: &str) -> Result<Self::Output> {
todo!() let map = HikingMap::new(input);
Ok(map.hike_ver_two())
} }
} }

View file

@ -9,8 +9,23 @@ macro_rules! define_solution {
} }
define_solution!( define_solution!(
day_1, day_2, day_3, day_4, day_5, day_6, day_7, day_8, day_9, day_10, day_11, day_12, day_13, day_1, day_2, day_3, day_4, day_5, day_6, day_7, day_8, day_9,
day_14, day_15, day_16, day_17, day_18, day_19, day_20, day_21, day_22, day_23, day_24, day_25, day_10,
// day_11,
// day_12,
// day_13,
// day_14,
// day_15,
// day_16,
// day_17,
// day_18,
// day_19,
// day_20,
// day_21,
// day_22,
// day_23,
// day_24,
// day_25,
); );
pub trait AocSolution { pub trait AocSolution {

View file

@ -13,9 +13,20 @@ pub struct Coord<U: Unit> {
} }
impl<U: Unit> Coord<U> { impl<U: Unit> Coord<U> {
#[inline(always)]
pub const fn new(x: U, y: U) -> Self { pub const fn new(x: U, y: U) -> Self {
Self { x, y } Self { x, y }
} }
#[inline(always)]
pub fn surround(&self) -> [Self; 4] {
[
Self::new(self.x - U::from(1), self.y),
Self::new(self.x, self.y + U::from(1)),
Self::new(self.x + U::from(1), self.y),
Self::new(self.x, self.y - U::from(1)),
]
}
} }
impl<U: Unit> Add for Coord<U> { impl<U: Unit> Add for Coord<U> {