day10, part1
This commit is contained in:
parent
d1b628fff1
commit
81f7933cc0
1 changed files with 161 additions and 2 deletions
|
@ -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(¤t) {
|
||||||
|
q.push(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut do_top = true;
|
||||||
|
let nexts = grid.next_step(¤t);
|
||||||
|
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(¤t).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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue