feat(day10): init
This commit is contained in:
parent
aae28d30eb
commit
55833d081c
2 changed files with 142 additions and 0 deletions
140
src/solutions/day_10.rs
Normal file
140
src/solutions/day_10.rs
Normal file
|
@ -0,0 +1,140 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use crate::common::{Answer, Solution};
|
||||
|
||||
pub struct Day10;
|
||||
|
||||
impl Solution for Day10 {
|
||||
fn name(&self) -> &'static str {
|
||||
"Hoof It"
|
||||
}
|
||||
|
||||
fn part_a(&self, input: &str) -> Answer {
|
||||
let grid = input
|
||||
.lines()
|
||||
.map(|l| {
|
||||
l.chars()
|
||||
.map(|c| c.to_digit(10).unwrap())
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
grid.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(x, l)| {
|
||||
l.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, n)| **n == 0)
|
||||
.map(move |(y, _)| (x, y))
|
||||
})
|
||||
.map(|(start_x, start_y)| {
|
||||
let mut robots = HashSet::new();
|
||||
robots.insert(Robot(start_x, start_y));
|
||||
|
||||
while !robots.iter().all(|r| r.is_done(&grid)) {
|
||||
robots = robots
|
||||
.into_iter()
|
||||
.flat_map(|r| r.propagate(&grid))
|
||||
.collect();
|
||||
}
|
||||
|
||||
robots.len()
|
||||
})
|
||||
.sum::<usize>()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn part_b(&self, input: &str) -> Answer {
|
||||
let grid = input
|
||||
.lines()
|
||||
.map(|l| {
|
||||
l.chars()
|
||||
.map(|c| c.to_digit(10).unwrap())
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
grid.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(x, l)| {
|
||||
l.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, n)| **n == 0)
|
||||
.map(move |(y, _)| (x, y))
|
||||
})
|
||||
.map(|(start_x, start_y)| {
|
||||
let mut robots = vec![Robot(start_x, start_y)];
|
||||
|
||||
while !robots.iter().all(|r| r.is_done(&grid)) {
|
||||
robots = robots
|
||||
.into_iter()
|
||||
.flat_map(|r| r.propagate(&grid))
|
||||
.collect();
|
||||
}
|
||||
|
||||
robots.len()
|
||||
})
|
||||
.sum::<usize>()
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Hash, PartialEq, Eq)]
|
||||
struct Robot(usize, usize);
|
||||
|
||||
impl Robot {
|
||||
fn is_done(&self, grid: &[Vec<u32>]) -> bool {
|
||||
grid[self.0][self.1] == 9
|
||||
}
|
||||
|
||||
fn propagate(self, grid: &[Vec<u32>]) -> Vec<Self> {
|
||||
if self.is_done(grid) {
|
||||
vec![self]
|
||||
} else {
|
||||
let max_x = grid.len() - 1;
|
||||
let max_y = grid[0].len() - 1;
|
||||
let current = grid[self.0][self.1];
|
||||
|
||||
[
|
||||
self.0.checked_sub(1).map(|n| (n, self.1)),
|
||||
(self.0 < max_x).then(|| (self.0 + 1, self.1)),
|
||||
self.1.checked_sub(1).map(|n| (self.0, n)),
|
||||
(self.1 < max_y).then(|| (self.0, self.1 + 1)),
|
||||
]
|
||||
.iter()
|
||||
.filter_map(|o| *o)
|
||||
.filter(|(x, y)| grid[*x][*y] == current + 1)
|
||||
.map(|(x, y)| Self(x, y))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::Day10;
|
||||
use crate::common::Solution;
|
||||
|
||||
use indoc::indoc;
|
||||
|
||||
const INPUT: &str = indoc! {"
|
||||
89010123
|
||||
78121874
|
||||
87430965
|
||||
96549874
|
||||
45678903
|
||||
32019012
|
||||
01329801
|
||||
10456732
|
||||
"};
|
||||
|
||||
#[test]
|
||||
fn part_a() {
|
||||
assert_eq!(Day10.part_a(INPUT), 36.into());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part_b() {
|
||||
assert_eq!(Day10.part_b(INPUT), 81.into());
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ mod day_06;
|
|||
mod day_07;
|
||||
mod day_08;
|
||||
mod day_09;
|
||||
mod day_10;
|
||||
|
||||
pub const SOLUTIONS: &[&dyn Solution] = &[
|
||||
&day_01::Day01,
|
||||
|
@ -20,4 +21,5 @@ pub const SOLUTIONS: &[&dyn Solution] = &[
|
|||
&day_07::Day07,
|
||||
&day_08::Day08,
|
||||
&day_09::Day09,
|
||||
&day_10::Day10,
|
||||
];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue