day10, part1

This commit is contained in:
Joe Ardent 2025-01-05 20:20:20 -08:00
parent d1b628fff1
commit 81f7933cc0

View file

@ -1,13 +1,172 @@
use std::collections::HashSet;
fn main() { fn main() {
println!("Hello, world!"); let input = std::fs::read_to_string("input").unwrap();
let grid = Grid::new(&input);
println!("{}", pt1(&grid));
} }
fn pt1(grid: &Grid) -> usize {
dfs(grid)
}
fn dfs(grid: &Grid) -> usize {
let mut total = 0;
for head in grid.heads.iter() {
let mut processed = HashSet::new();
let mut q = Vec::new();
q.push(*head);
while let Some(current) = q.pop() {
if !processed.contains(&current) {
q.push(current);
}
let mut do_top = true;
let nexts = grid.next_step(&current);
for next in nexts.iter() {
if !processed.contains(next) {
q.push(*next);
do_top = false;
}
}
if do_top {
let _ = q.pop();
processed.insert(current);
if grid.get(&current).unwrap() == 9 {
total += 1;
}
}
}
}
total
}
#[derive(Debug, Clone)]
struct Grid { struct Grid {
rows: Vec<Vec<usize>>, rows: Vec<Vec<usize>>,
heads: Vec<Loc>,
} }
impl Grid { impl Grid {
fn new(input: &str) -> Self { fn new(input: &str) -> Self {
todo!() let mut rows = Vec::new();
let mut heads = Vec::new();
for (row, line) in input.lines().enumerate() {
let row = line
.chars()
.enumerate()
.map(|(col, c)| {
let n = c.to_digit(10).unwrap() as usize;
if n == 0 {
heads.push(Loc { row, col });
}
n
})
.collect();
rows.push(row);
}
Self { rows, heads }
}
fn get(&self, loc: &Loc) -> Option<usize> {
self.rows
.get(loc.row)
.and_then(|row| row.get(loc.col).copied())
}
fn next(&self, loc: &Loc) -> Vec<Tile> {
let Loc { row, col } = *loc;
let mut out = Vec::new();
// north
{
let row = row.wrapping_sub(1);
if let Some(&alt) = self.rows.get(row).and_then(|r| r.get(col)) {
out.push(Tile {
alt,
loc: Loc { row, col },
});
}
}
// south
{
let row = row + 1;
if let Some(&alt) = self.rows.get(row).and_then(|r| r.get(col)) {
out.push(Tile {
alt,
loc: Loc { row, col },
});
}
}
// east
{
let col = col + 1;
if let Some(&alt) = self.rows.get(row).and_then(|r| r.get(col)) {
out.push(Tile {
alt,
loc: Loc { row, col },
});
}
}
// west
{
let col = col.wrapping_sub(1);
if let Some(&alt) = self.rows.get(row).and_then(|r| r.get(col)) {
out.push(Tile {
alt,
loc: Loc { row, col },
});
}
}
out
}
fn next_step(&self, loc: &Loc) -> Vec<Loc> {
let alt = self.rows[loc.row][loc.col];
let target = alt + 1;
self.next(loc)
.iter()
.filter_map(|t| if t.alt == target { Some(t.loc) } else { None })
.collect()
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
struct Loc {
row: usize,
col: usize,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
struct Tile {
loc: Loc,
alt: usize,
}
#[cfg(test)]
mod test {
use super::*;
static INPUT: &str = "89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732";
#[test]
fn p1() {
let g = Grid::new(INPUT);
assert_eq!(36, pt1(&g));
} }
} }