2024: day 10: part 1 and 2: rust
This commit is contained in:
parent
9347243eee
commit
8367b63c53
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "day10"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
|
@ -0,0 +1,96 @@
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
|
fn parse_map(string: String) -> Vec<Vec<u32>> {
|
||||||
|
let mut map: Vec<Vec<u32>> = Vec::new();
|
||||||
|
for line in string.lines() {
|
||||||
|
let mut map_slice: Vec<u32> = Vec::new();
|
||||||
|
for letter in line.chars() {
|
||||||
|
let height: u32 = letter.to_digit(10).unwrap();
|
||||||
|
map_slice.push(height);
|
||||||
|
}
|
||||||
|
map.push(map_slice);
|
||||||
|
}
|
||||||
|
map
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_in_bound(x: isize, y: isize, width: usize, height: usize) -> bool {
|
||||||
|
x >= 0 && y >= 0 && y < height as isize && x < width as isize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn trailhead_score(start_x: usize, start_y: usize, map: &Vec<Vec<u32>>) -> u32 {
|
||||||
|
let mut visited: BTreeSet<(usize, usize)> = BTreeSet::new();
|
||||||
|
let mut score: u32 = 0;
|
||||||
|
let mut queue: Vec<(usize, usize)> = Vec::new();
|
||||||
|
queue.push((start_x, start_y));
|
||||||
|
let moves: [(isize, isize); 4] = [(-1, 0), (0, -1), (1, 0), (0, 1)];
|
||||||
|
while !queue.is_empty() {
|
||||||
|
if let Some((x, y)) = queue.pop() {
|
||||||
|
if map[y][x] == 9 {
|
||||||
|
score += 1;
|
||||||
|
}
|
||||||
|
for (dx, dy) in moves {
|
||||||
|
let new_x = x as isize + dx;
|
||||||
|
let new_y = y as isize + dy;
|
||||||
|
if is_in_bound(new_x, new_y, map[0].len(), map.len())
|
||||||
|
&& map[new_y as usize][new_x as usize] > map[y][x]
|
||||||
|
&& map[new_y as usize][new_x as usize] - map[y][x] == 1
|
||||||
|
&& !visited.contains(&(new_x as usize, new_y as usize)) {
|
||||||
|
queue.push((new_x as usize, new_y as usize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visited.insert((x as usize, y as usize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
score
|
||||||
|
}
|
||||||
|
|
||||||
|
fn trailhead_paths(x: usize, y: usize, map: &Vec<Vec<u32>>) -> u32 {
|
||||||
|
if map[y][x] == 9 {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
let moves: [(isize, isize); 4] = [(-1, 0), (0, -1), (1, 0), (0, 1)];
|
||||||
|
let mut paths: u32 = 0;
|
||||||
|
for (dx, dy) in moves {
|
||||||
|
let new_x = x as isize + dx;
|
||||||
|
let new_y = y as isize + dy;
|
||||||
|
if is_in_bound(new_x, new_y, map[0].len(), map.len())
|
||||||
|
&& map[new_y as usize][new_x as usize] > map[y][x]
|
||||||
|
&& map[new_y as usize][new_x as usize] - map[y][x] == 1 {
|
||||||
|
let p = trailhead_paths(new_x as usize, new_y as usize, map);
|
||||||
|
paths += p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_trailheads(map: &Vec<Vec<u32>>) -> Vec<(usize, usize)> {
|
||||||
|
let mut trailheads: Vec<(usize, usize)> = Vec::new();
|
||||||
|
for y in 0..map.len() {
|
||||||
|
for x in 0..map[y].len() {
|
||||||
|
if map[y][x] == 0 {
|
||||||
|
trailheads.push((x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trailheads
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> std::io::Result<()> {
|
||||||
|
let input = std::io::read_to_string(std::io::stdin())?;
|
||||||
|
let map = parse_map(input);
|
||||||
|
let trailheads = find_trailheads(&map);
|
||||||
|
// Part 1.
|
||||||
|
let mut score = 0;
|
||||||
|
for (start_x, start_y) in &trailheads {
|
||||||
|
score += trailhead_score(*start_x, *start_y, &map);
|
||||||
|
}
|
||||||
|
println!("{}", score);
|
||||||
|
// Part 2.
|
||||||
|
let mut paths = 0;
|
||||||
|
for (start_x, start_y) in &trailheads {
|
||||||
|
paths += trailhead_paths(*start_x, *start_y, &map);
|
||||||
|
}
|
||||||
|
println!("{}", paths);
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue